ationError: " : "DeprecationWarning: ";
  deprecationMessage += `'${name}' `;
  deprecationMessage += since ? `has been deprecated since v${since}` : "is deprecated";
  deprecationMessage += error2 ? " and can no longer be used." : errorAfter ? ` and will no longer be usable after v${errorAfter}.` : ".";
  deprecationMessage += message ? ` ${formatStringFromArgs(message, [name])}` : "";
  return deprecationMessage;
}
function createErrorDeprecation(name, errorAfter, since, message) {
  const deprecationMessage = formatDeprecationMessage(
    name,
    /*error*/
    true,
    errorAfter,
    since,
    message
  );
  return () => {
    throw new TypeError(deprecationMessage);
  };
}
function createWarningDeprecation(name, errorAfter, since, message) {
  let hasWrittenDeprecation = false;
  return () => {
    if (enableDeprecationWarnings && !hasWrittenDeprecation) {
      Debug.log.warn(formatDeprecationMessage(
        name,
        /*error*/
        false,
        errorAfter,
        since,
        message
      ));
      hasWrittenDeprecation = true;
    }
  };
}
function createDeprecation(name, options = {}) {
  const version2 = typeof options.typeScriptVersion === "string" ? new Version(options.typeScriptVersion) : options.typeScriptVersion ?? getTypeScriptVersion();
  const errorAfter = typeof options.errorAfter === "string" ? new Version(options.errorAfter) : options.errorAfter;
  const warnAfter = typeof options.warnAfter === "string" ? new Version(options.warnAfter) : options.warnAfter;
  const since = typeof options.since === "string" ? new Version(options.since) : options.since ?? warnAfter;
  const error2 = options.error || errorAfter && version2.compareTo(errorAfter) >= 0;
  const warn = !warnAfter || version2.compareTo(warnAfter) >= 0;
  return error2 ? createErrorDeprecation(name, errorAfter, since, options.message) : warn ? createWarningDeprecation(name, errorAfter, since, options.message) : noop;
}
function wrapFunction(deprecation, func) {
  return function() {
    deprecation();
    return func.apply(this, arguments);
  };
}
function deprecate(func, options) {
  const deprecation = createDeprecation((options == null ? void 0 : options.name) ?? Debug.getFunctionName(func), options);
  return wrapFunction(deprecation, func);
}

// src/deprecatedCompat/deprecations.ts
function createOverload(name, overloads, binder2, deprecations) {
  Object.defineProperty(call, "name", { ...Object.getOwnPropertyDescriptor(call, "name"), value: name });
  if (deprecations) {
    for (const key of Object.keys(deprecations)) {
      const index = +key;
      if (!isNaN(index) && hasProperty(overloads, `${index}`)) {
        overloads[index] = deprecate(overloads[index], { ...deprecations[index], name });
      }
    }
  }
  const bind = createBinder2(overloads, binder2);
  return call;
  function call(...args) {
    const index = bind(args);
    const fn = index !== void 0 ? overloads[index] : void 0;
    if (typeof fn === "function") {
      return fn(...args);
    }
    throw new TypeError("Invalid arguments");
  }
}
function createBinder2(overloads, binder2) {
  return (args) => {
    for (let i = 0; hasProperty(overloads, `${i}`) && hasProperty(binder2, `${i}`); i++) {
      const fn = binder2[i];
      if (fn(args)) {
        return i;
      }
    }
  };
}
function buildOverload(name) {
  return {
    overload: (overloads) => ({
      bind: (binder2) => ({
        finish: () => createOverload(name, overloads, binder2),
        deprecate: (deprecations) => ({
          finish: () => createOverload(name, overloads, binder2, deprecations)
        })
      })
    })
  };
}

// src/server/_namespaces/ts.server.ts
var ts_server_exports3 = {};
__export(ts_server_exports3, {
  ActionInvalidate: () => ActionInvalidate,
  ActionPackageInstalled: () => ActionPackageInstalled,
  ActionSet: () => ActionSet,
  ActionWatchTypingLocations: () => ActionWatchTypingLocations,
  Arguments: () => Arguments,
  AutoImportProviderProject: () => AutoImportProviderProject,
  AuxiliaryProject: () => AuxiliaryProject,
  CharRangeSection: () => CharRangeSection,
  CloseFileWatcherEvent: () => CloseFileWatcherEvent,
  CommandNames: () => CommandNames,
  ConfigFileDiagEvent: () => ConfigFileDiagEvent,
  ConfiguredProject: () => ConfiguredProject2,
  ConfiguredProjectLoadKind: () => ConfiguredProjectLoadKind,
  CreateDirectoryWatcherEvent: () => CreateDirectoryWatcherEvent,
  CreateFileWatcherEvent: () => CreateFileWatcherEvent,
  Errors: () => Errors,
  EventBeginInstallTypes: () => EventBeginInstallTypes,
  EventEndInstallTypes: () => EventEndInstallTypes,
  EventInitializationFailed: () => EventInitializationFailed,
  EventTypesRegistry: () => EventTypesRegistry,
  ExternalProject: () => ExternalProject,
  GcTimer: () => GcTimer,
  InferredProject: () => InferredProject2,
  LargeFileReferencedEvent: () => LargeFileReferencedEvent,
  LineIndex: () => LineIndex,
  LineLeaf: () => LineLeaf,
  LineNode: () => LineNode,
  LogLevel: () => LogLevel2,
  Msg: () => Msg,
  OpenFileInfoTelemetryEvent: () => OpenFileInfoTelemetryEvent,
  Project: () => Project2,
  ProjectInfoTelemetryEvent: () => ProjectInfoTelemetryEvent,
  ProjectKind: () => ProjectKind,
  ProjectLanguageServiceStateEvent: () => ProjectLanguageServiceStateEvent,
  ProjectLoadingFinishEvent: () => ProjectLoadingFinishEvent,
  ProjectLoadingStartEvent: () => ProjectLoadingStartEvent,
  ProjectService: () => ProjectService2,
  ProjectsUpdatedInBackgroundEvent: () => ProjectsUpdatedInBackgroundEvent,
  ScriptInfo: () => ScriptInfo,
  ScriptVersionCache: () => ScriptVersionCache,
  Session: () => Session3,
  TextStorage: () => TextStorage,
  ThrottledOperations: () => ThrottledOperations,
  TypingsInstallerAdapter: () => TypingsInstallerAdapter,
  allFilesAreJsOrDts: () => allFilesAreJsOrDts,
  allRootFilesAreJsOrDts: () => allRootFilesAreJsOrDts,
  asNormalizedPath: () => asNormalizedPath,
  convertCompilerOptions: () => convertCompilerOptions,
  convertFormatOptions: () => convertFormatOptions,
  convertScriptKindName: () => convertScriptKindName,
  convertTypeAcquisition: () => convertTypeAcquisition,
  convertUserPreferences: () => convertUserPreferences,
  convertWatchOptions: () => convertWatchOptions,
  countEachFileTypes: () => countEachFileTypes,
  createInstallTypingsRequest: () => createInstallTypingsRequest,
  createModuleSpecifierCache: () => createModuleSpecifierCache,
  createNormalizedPathMap: () => createNormalizedPathMap,
  createPackageJsonCache: () => createPackageJsonCache,
  createSortedArray: () => createSortedArray2,
  emptyArray: () => emptyArray2,
  findArgument: () => findArgument,
  formatDiagnosticToProtocol: () => formatDiagnosticToProtocol,
  formatMessage: () => formatMessage2,
  getBaseConfigFileName: () => getBaseConfigFileName,
  getLocationInNewDocument: () => getLocationInNewDocument,
  hasArgument: () => hasArgument,
  hasNoTypeScriptSource: () => hasNoTypeScriptSource,
  indent: () => indent2,
  isBackgroundProject: () => isBackgroundProject,
  isConfigFile: () => isConfigFile,
  isConfiguredProject: () => isConfiguredProject,
  isDynamicFileName: () => isDynamicFileName,
  isExternalProject: () => isExternalProject,
  isInferredProject: () => isInferredProject,
  isInferredProjectName: () => isInferredProjectName,
  isProjectDeferredClose: () => isProjectDeferredClose,
  makeAutoImportProviderProjectName: () => makeAutoImportProviderProjectName,
  makeAuxiliaryProjectName: () => makeAuxiliaryProjectName,
  makeInferredProjectName: () => makeInferredProjectName,
  maxFileSize: () => maxFileSize,
  maxProgramSizeForNonTsFiles: () => maxProgramSizeForNonTsFiles,
  normalizedPathToPath: () => normalizedPathToPath,
  nowString: () => nowString,
  nullCancellationToken: () => nullCancellationToken,
  nullTypingsInstaller: () => nullTypingsInstaller,
  protocol: () => ts_server_protocol_exports,
  stringifyIndented: () => stringifyIndented,
  toEvent: () => toEvent,
  toNormalizedPath: () => toNormalizedPath,
  tryConvertScriptKindName: () => tryConvertScriptKindName,
  typingsInstaller: () => ts_server_typingsInstaller_exports,
  updateProjectIfDirty: () => updateProjectIfDirty
});

// src/typingsInstallerCore/_namespaces/ts.server.typingsInstaller.ts
var ts_server_typingsInstaller_exports = {};
__export(ts_server_typingsInstaller_exports, {
  TypingsInstaller: () => TypingsInstaller,
  getNpmCommandForInstallation: () => getNpmCommandForInstallation,
  installNpmPackages: () => installNpmPackages,
  typingsName: () => typingsName
});

// src/typingsInstallerCore/typingsInstaller.ts
var nullLog = {
  isEnabled: () => false,
  writeLine: noop
};
function typingToFileName(cachePath, packageName, installTypingHost, log) {
  try {
    const result = resolveModuleName(packageName, combinePaths(cachePath, "index.d.ts"), { moduleResolution: 2 /* Node10 */ }, installTypingHost);
    return result.resolvedModule && result.resolvedModule.resolvedFileName;
  } catch (e) {
    if (log.isEnabled()) {
      log.writeLine(`Failed to resolve ${packageName} in folder '${cachePath}': ${e.message}`);
    }
    return void 0;
  }
}
function installNpmPackages(npmPath, tsVersion, packageNames, install) {
  let hasError = false;
  for (let remaining = packageNames.length; remaining > 0; ) {
    const result = getNpmCommandForInstallation(npmPath, tsVersion, packageNames, remaining);
    remaining = result.remaining;
    hasError = install(result.command) || hasError;
  }
  return hasError;
}
function getNpmCommandForInstallation(npmPath, tsVersion, packageNames, remaining) {
  const sliceStart = packageNames.length - remaining;
  let command, toSlice = remaining;
  while (true) {
    command = `${npmPath} install --ignore-scripts ${(toSlice === packageNames.length ? packageNames : packageNames.slice(sliceStart, sliceStart + toSlice)).join(" ")} --save-dev --user-agent="typesInstaller/${tsVersion}"`;
    if (command.length < 8e3) {
      break;
    }
    toSlice = toSlice - Math.floor(toSlice / 2);
  }
  return { command, remaining: remaining - toSlice };
}
var TypingsInstaller = class {
  constructor(installTypingHost, globalCachePath, safeListPath, typesMapLocation, throttleLimit, log = nullLog) {
    this.installTypingHost = installTypingHost;
    this.globalCachePath = globalCachePath;
    this.safeListPath = safeListPath;
    this.typesMapLocation = typesMapLocation;
    this.throttleLimit = throttleLimit;
    this.log = log;
    this.packageNameToTypingLocation = /* @__PURE__ */ new Map();
    this.missingTypingsSet = /* @__PURE__ */ new Set();
    this.knownCachesSet = /* @__PURE__ */ new Set();
    this.projectWatchers = /* @__PURE__ */ new Map();
    this.pendingRunRequests = [];
    this.installRunCount = 1;
    this.inFlightRequestCount = 0;
    // eslint-disable-line @typescript-eslint/unified-signatures
    this.latestDistTag = "latest";
    const isLoggingEnabled = this.log.isEnabled();
    if (isLoggingEnabled) {
      this.log.writeLine(`Global cache location '${globalCachePath}', safe file path '${safeListPath}', types map path ${typesMapLocation}`);
    }
    this.processCacheLocation(this.globalCachePath);
  }
  /** @internal */
  handleRequest(req) {
    switch (req.kind) {
      case "discover":
        this.install(req);
        break;
      case "closeProject":
        this.closeProject(req);
        break;
      case "typesRegistry": {
        const typesRegistry = {};
        this.typesRegistry.forEach((value, key) => {
          typesRegistry[key] = value;
        });
        const response = { kind: EventTypesRegistry, typesRegistry };
        this.sendResponse(response);
        break;
      }
      case "installPackage": {
        this.installPackage(req);
        break;
      }
      default:
        Debug.assertNever(req);
    }
  }
  closeProject(req) {
    this.closeWatchers(req.projectName);
  }
  closeWatchers(projectName) {
    if (this.log.isEnabled()) {
      this.log.writeLine(`Closing file watchers for project '${projectName}'`);
    }
    const watchers = this.projectWatchers.get(projectName);
    if (!watchers) {
      if (this.log.isEnabled()) {
        this.log.writeLine(`No watchers are registered for project '${projectName}'`);
      }
      return;
    }
    this.projectWatchers.delete(projectName);
    this.sendResponse({ kind: ActionWatchTypingLocations, projectName, files: [] });
    if (this.log.isEnabled()) {
      this.log.writeLine(`Closing file watchers for project '${projectName}' - done.`);
    }
  }
  install(req) {
    if (this.log.isEnabled()) {
      this.log.writeLine(`Got install request${stringifyIndented(req)}`);
    }
    if (req.cachePath) {
      if (this.log.isEnabled()) {
        this.log.writeLine(`Request specifies cache path '${req.cachePath}', loading cached information...`);
      }
      this.processCacheLocation(req.cachePath);
    }
    if (this.safeList === void 0) {
      this.initializeSafeList();
    }
    const discoverTypingsResult = ts_JsTyping_exports.discoverTypings(
      this.installTypingHost,
      this.log.isEnabled() ? (s) => this.log.writeLine(s) : void 0,
      req.fileNames,
      req.projectRootPath,
      this.safeList,
      this.packageNameToTypingLocation,
      req.typeAcquisition,
      req.unresolvedImports,
      this.typesRegistry,
      req.compilerOptions
    );
    this.watchFiles(req.projectName, discoverTypingsResult.filesToWatch);
    if (discoverTypingsResult.newTypingNames.length) {
      this.installTypings(req, req.cachePath || this.globalCachePath, discoverTypingsResult.cachedTypingPaths, discoverTypingsResult.newTypingNames);
    } else {
      this.sendResponse(this.createSetTypings(req, discoverTypingsResult.cachedTypingPaths));
      if (this.log.isEnabled()) {
        this.log.writeLine(`No new typings were requested as a result of typings discovery`);
      }
    }
  }
  /** @internal */
  installPackage(req) {
    const { fileName, packageName, projectName, projectRootPath, id } = req;
    const cwd = forEachAncestorDirectory(getDirectoryPath(fileName), (directory) => {
      if (this.installTypingHost.fileExists(combinePaths(directory, "package.json"))) {
        return directory;
      }
    }) || projectRootPath;
    if (cwd) {
      this.installWorker(-1, [packageName], cwd, (success) => {
        const message = success ? `Package ${packageName} installed.` : `There was an error installing ${packageName}.`;
        const response = {
          kind: ActionPackageInstalled,
          projectName,
          id,
          success,
          message
        };
        this.sendResponse(response);
      });
    } else {
      const response = {
        kind: ActionPackageInstalled,
        projectName,
        id,
        success: false,
        message: "Could not determine a project root path."
      };
      this.sendResponse(response);
    }
  }
  initializeSafeList() {
    if (this.typesMapLocation) {
      const safeListFromMap = ts_JsTyping_exports.loadTypesMap(this.installTypingHost, this.typesMapLocation);
      if (safeListFromMap) {
        this.log.writeLine(`Loaded safelist from types map file '${this.typesMapLocation}'`);
        this.safeList = safeListFromMap;
        return;
      }
      this.log.writeLine(`Failed to load safelist from types map file '${this.typesMapLocation}'`);
    }
    this.safeList = ts_JsTyping_exports.loadSafeList(this.installTypingHost, this.safeListPath);
  }
  processCacheLocation(cacheLocation) {
    if (this.log.isEnabled()) {
      this.log.writeLine(`Processing cache location '${cacheLocation}'`);
    }
    if (this.knownCachesSet.has(cacheLocation)) {
      if (this.log.isEnabled()) {
        this.log.writeLine(`Cache location was already processed...`);
      }
      return;
    }
    const packageJson = combinePaths(cacheLocation, "package.json");
    const packageLockJson = combinePaths(cacheLocation, "package-lock.json");
    if (this.log.isEnabled()) {
      this.log.writeLine(`Trying to find '${packageJson}'...`);
    }
    if (this.installTypingHost.fileExists(packageJson) && this.installTypingHost.fileExists(packageLockJson)) {
      const npmConfig = JSON.parse(this.installTypingHost.readFile(packageJson));
      const npmLock = JSON.parse(this.installTypingHost.readFile(packageLockJson));
      if (this.log.isEnabled()) {
        this.log.writeLine(`Loaded content of '${packageJson}':${stringifyIndented(npmConfig)}`);
        this.log.writeLine(`Loaded content of '${packageLockJson}':${stringifyIndented(npmLock)}`);
      }
      if (npmConfig.devDependencies && npmLock.dependencies) {
        for (const key in npmConfig.devDependencies) {
          if (!hasProperty(npmLock.dependencies, key)) {
            continue;
          }
          const packageName = getBaseFileName(key);
          if (!packageName) {
            continue;
          }
          const typingFile = typingToFileName(cacheLocation, packageName, this.installTypingHost, this.log);
          if (!typingFile) {
            this.missingTypingsSet.add(packageName);
            continue;
          }
          const existingTypingFile = this.packageNameToTypingLocation.get(packageName);
          if (existingTypingFile) {
            if (existingTypingFile.typingLocation === typingFile) {
              continue;
            }
            if (this.log.isEnabled()) {
              this.log.writeLine(`New typing for package ${packageName} from '${typingFile}' conflicts with existing typing file '${existingTypingFile}'`);
            }
          }
          if (this.log.isEnabled()) {
            this.log.writeLine(`Adding entry into typings cache: '${packageName}' => '${typingFile}'`);
          }
          const info = getProperty(npmLock.dependencies, key);
          const version2 = info && info.version;
          if (!version2) {
            continue;
          }
          const newTyping = { typingLocation: typingFile, version: new Version(version2) };
          this.packageNameToTypingLocation.set(packageName, newTyping);
        }
      }
    }
    if (this.log.isEnabled()) {
      this.log.writeLine(`Finished processing cache location '${cacheLocation}'`);
    }
    this.knownCachesSet.add(cacheLocation);
  }
  filterTypings(typingsToInstall) {
    return mapDefined(typingsToInstall, (typing) => {
      const typingKey = mangleScopedPackageName(typing);
      if (this.missingTypingsSet.has(typingKey)) {
        if (this.log.isEnabled()) this.log.writeLine(`'${typing}':: '${typingKey}' is in missingTypingsSet - skipping...`);
        return void 0;
      }
      const validationResult = ts_JsTyping_exports.validatePackageName(typing);
      if (validationResult !== ts_JsTyping_exports.NameValidationResult.Ok) {
        this.missingTypingsSet.add(typingKey);
        if (this.log.isEnabled()) this.log.writeLine(ts_JsTyping_exports.renderPackageNameValidationFailure(validationResult, typing));
        return void 0;
      }
      if (!this.typesRegistry.has(typingKey)) {
        if (this.log.isEnabled()) this.log.writeLine(`'${typing}':: Entry for package '${typingKey}' does not exist in local types registry - skipping...`);
        return void 0;
      }
      if (this.packageNameToTypingLocation.get(typingKey) && ts_JsTyping_exports.isTypingUpToDate(this.packageNameToTypingLocation.get(typingKey), this.typesRegistry.get(typingKey))) {
        if (this.log.isEnabled()) this.log.writeLine(`'${typing}':: '${typingKey}' already has an up-to-date typing - skipping...`);
        return void 0;
      }
      return typingKey;
    });
  }
  ensurePackageDirectoryExists(directory) {
    const npmConfigPath = combinePaths(directory, "package.json");
    if (this.log.isEnabled()) {
      this.log.writeLine(`Npm config file: ${npmConfigPath}`);
    }
    if (!this.installTypingHost.fileExists(npmConfigPath)) {
      if (this.log.isEnabled()) {
        this.log.writeLine(`Npm config file: '${npmConfigPath}' is missing, creating new one...`);
      }
      this.ensureDirectoryExists(directory, this.installTypingHost);
      this.installTypingHost.writeFile(npmConfigPath, '{ "private": true }');
    }
  }
  installTypings(req, cachePath, currentlyCachedTypings, typingsToInstall) {
    if (this.log.isEnabled()) {
      this.log.writeLine(`Installing typings ${JSON.stringify(typingsToInstall)}`);
    }
    const filteredTypings = this.filterTypings(typingsToInstall);
    if (filteredTypings.length === 0) {
      if (this.log.isEnabled()) {
        this.log.writeLine(`All typings are known to be missing or invalid - no need to install more typings`);
      }
      this.sendResponse(this.createSetTypings(req, currentlyCachedTypings));
      return;
    }
    this.ensurePackageDirectoryExists(cachePath);
    const requestId = this.installRunCount;
    this.installRunCount++;
    this.sendResponse({
      kind: EventBeginInstallTypes,
      eventId: requestId,
      typingsInstallerVersion: version,
      projectName: req.projectName
    });
    const scopedTypings = filteredTypings.map(typingsName);
    this.installTypingsAsync(requestId, scopedTypings, cachePath, (ok) => {
      try {
        if (!ok) {
          if (this.log.isEnabled()) {
            this.log.writeLine(`install request failed, marking packages as missing to prevent repeated requests: ${JSON.stringify(filteredTypings)}`);
          }
          for (const typing of filteredTypings) {
            this.missingTypingsSet.add(typing);
          }
          return;
        }
        if (this.log.isEnabled()) {
          this.log.writeLine(`Installed typings ${JSON.stringify(scopedTypings)}`);
        }
        const installedTypingFiles = [];
        for (const packageName of filteredTypings) {
          const typingFile = typingToFileName(cachePath, packageName, this.installTypingHost, this.log);
          if (!typingFile) {
            this.missingTypingsSet.add(packageName);
            continue;
          }
          const distTags = this.typesRegistry.get(packageName);
          const newVersion = new Version(distTags[`ts${versionMajorMinor}`] || distTags[this.latestDistTag]);
          const newTyping = { typingLocation: typingFile, version: newVersion };
          this.packageNameToTypingLocation.set(packageName, newTyping);
          installedTypingFiles.push(typingFile);
        }
        if (this.log.isEnabled()) {
          this.log.writeLine(`Installed typing files ${JSON.stringify(installedTypingFiles)}`);
        }
        this.sendResponse(this.createSetTypings(req, currentlyCachedTypings.concat(installedTypingFiles)));
      } finally {
        const response = {
          kind: EventEndInstallTypes,
          eventId: requestId,
          projectName: req.projectName,
          packagesToInstall: scopedTypings,
          installSuccess: ok,
          typingsInstallerVersion: version
        };
        this.sendResponse(response);
      }
    });
  }
  ensureDirectoryExists(directory, host) {
    const directoryName = getDirectoryPath(directory);
    if (!host.directoryExists(directoryName)) {
      this.ensureDirectoryExists(directoryName, host);
    }
    if (!host.directoryExists(directory)) {
      host.createDirectory(directory);
    }
  }
  watchFiles(projectName, files) {
    if (!files.length) {
      this.closeWatchers(projectName);
      return;
    }
    const existing = this.projectWatchers.get(projectName);
    const newSet = new Set(files);
    if (!existing || forEachKey(newSet, (s) => !existing.has(s)) || forEachKey(existing, (s) => !newSet.has(s))) {
      this.projectWatchers.set(projectName, newSet);
      this.sendResponse({ kind: ActionWatchTypingLocations, projectName, files });
    } else {
      this.sendResponse({ kind: ActionWatchTypingLocations, projectName, files: void 0 });
    }
  }
  createSetTypings(request, typings) {
    return {
      projectName: request.projectName,
      typeAcquisition: request.typeAcquisition,
      compilerOptions: request.compilerOptions,
      typings,
      unresolvedImports: request.unresolvedImports,
      kind: ActionSet
    };
  }
  installTypingsAsync(requestId, packageNames, cwd, onRequestCompleted) {
    this.pendingRunRequests.unshift({ requestId, packageNames, cwd, onRequestCompleted });
    this.executeWithThrottling();
  }
  executeWithThrottling() {
    while (this.inFlightRequestCount < this.throttleLimit && this.pendingRunRequests.length) {
      this.inFlightRequestCount++;
      const request = this.pendingRunRequests.pop();
      this.installWorker(request.requestId, request.packageNames, request.cwd, (ok) => {
        this.inFlightRequestCount--;
        request.onRequestCompleted(ok);
        this.executeWithThrottling();
      });
    }
  }
};
function typingsName(packageName) {
  return `@types/${packageName}@ts${versionMajorMinor}`;
}

// src/server/utilitiesPublic.ts
var LogLevel2 = /* @__PURE__ */ ((LogLevel3) => {
  LogLevel3[LogLevel3["terse"] = 0] = "terse";
  LogLevel3[LogLevel3["normal"] = 1] = "normal";
  LogLevel3[LogLevel3["requestTime"] = 2] = "requestTime";
  LogLevel3[LogLevel3["verbose"] = 3] = "verbose";
  return LogLevel3;
})(LogLevel2 || {});
var emptyArray2 = createSortedArray2();
var Msg = /* @__PURE__ */ ((Msg2) => {
  Msg2["Err"] = "Err";
  Msg2["Info"] = "Info";
  Msg2["Perf"] = "Perf";
  return Msg2;
})(Msg || {});
function createInstallTypingsRequest(project, typeAcquisition, unresolvedImports, cachePath) {
  return {
    projectName: project.getProjectName(),
    fileNames: project.getFileNames(
      /*excludeFilesFromExternalLibraries*/
      true,
      /*excludeConfigFiles*/
      true
    ).concat(project.getExcludedFiles()),
    compilerOptions: project.getCompilationSettings(),
    typeAcquisition,
    unresolvedImports,
    projectRootPath: project.getCurrentDirectory(),
    cachePath,
    kind: "discover"
  };
}
var Errors;
((Errors2) => {
  function ThrowNoProject() {
    throw new Error("No Project.");
  }
  Errors2.ThrowNoProject = ThrowNoProject;
  function ThrowProjectLanguageServiceDisabled() {
    throw new Error("The project's language service is disabled.");
  }
  Errors2.ThrowProjectLanguageServiceDisabled = ThrowProjectLanguageServiceDisabled;
  function ThrowProjectDoesNotContainDocument(fileName, project) {
    throw new Error(`Project '${project.getProjectName()}' does not contain document '${fileName}'`);
  }
  Errors2.ThrowProjectDoesNotContainDocument = ThrowProjectDoesNotContainDocument;
})(Errors || (Errors = {}));
function toNormalizedPath(fileName) {
  return normalizePath(fileName);
}
function normalizedPathToPath(normalizedPath, currentDirectory, getCanonicalFileName) {
  const f = isRootedDiskPath(normalizedPath) ? normalizedPath : getNormalizedAbsolutePath(normalizedPath, currentDirectory);
  return getCanonicalFileName(f);
}
function asNormalizedPath(fileName) {
  return fileName;
}
function createNormalizedPathMap() {
  const map2 = /* @__PURE__ */ new Map();
  return {
    get(path) {
      return map2.get(path);
    },
    set(path, value) {
      map2.set(path, value);
    },
    contains(path) {
      return map2.has(path);
    },
    remove(path) {
      map2.delete(path);
    }
  };
}
function isInferredProjectName(name) {
  return /dev\/null\/inferredProject\d+\*/.test(name);
}
function makeInferredProjectName(counter) {
  return `/dev/null/inferredProject${counter}*`;
}
function makeAutoImportProviderProjectName(counter) {
  return `/dev/null/autoImportProviderProject${counter}*`;
}
function makeAuxiliaryProjectName(counter) {
  return `/dev/null/auxiliaryProject${counter}*`;
}
function createSortedArray2() {
  return [];
}

// src/server/utilities.ts
var ThrottledOperations = class _ThrottledOperations {
  constructor(host, logger) {
    this.host = host;
    this.pendingTimeouts = /* @__PURE__ */ new Map();
    this.logger = logger.hasLevel(3 /* verbose */) ? logger : void 0;
  }
  /**
   * Wait `number` milliseconds and then invoke `cb`.  If, while waiting, schedule
   * is called again with the same `operationId`, cancel this operation in favor
   * of the new one.  (Note that the amount of time the canceled operation had been
   * waiting does not affect the amount of time that the new operation waits.)
   */
  schedule(operationId, delay, cb) {
    const pendingTimeout = this.pendingTimeouts.get(operationId);
    if (pendingTimeout) {
      this.host.clearTimeout(pendingTimeout);
    }
    this.pendingTimeouts.set(operationId, this.host.setTimeout(_ThrottledOperations.run, delay, operationId, this, cb));
    if (this.logger) {
      this.logger.info(`Scheduled: ${operationId}${pendingTimeout ? ", Cancelled earlier one" : ""}`);
    }
  }
  cancel(operationId) {
    const pendingTimeout = this.pendingTimeouts.get(operationId);
    if (!pendingTimeout) return false;
    this.host.clearTimeout(pendingTimeout);
    return this.pendingTimeouts.delete(operationId);
  }
  static run(operationId, self, cb) {
    self.pendingTimeouts.delete(operationId);
    if (self.logger) {
      self.logger.info(`Running: ${operationId}`);
    }
    cb();
  }
};
var GcTimer = class _GcTimer {
  constructor(host, delay, logger) {
    this.host = host;
    this.delay = delay;
    this.logger = logger;
  }
  scheduleCollect() {
    if (!this.host.gc || this.timerId !== void 0) {
      return;
    }
    this.timerId = this.host.setTimeout(_GcTimer.run, this.delay, this);
  }
  static run(self) {
    self.timerId = void 0;
    const log = self.logger.hasLevel(2 /* requestTime */);
    const before = log && self.host.getMemoryUsage();
    self.host.gc();
    if (log) {
      const after = self.host.getMemoryUsage();
      self.logger.perftrc(`GC::before ${before}, after ${after}`);
    }
  }
};
function getBaseConfigFileName(configFilePath) {
  const base = getBaseFileName(configFilePath);
  return base === "tsconfig.json" || base === "jsconfig.json" ? base : void 0;
}

// src/server/_namespaces/ts.server.protocol.ts
var ts_server_protocol_exports = {};
__export(ts_server_protocol_exports, {
  ClassificationType: () => ClassificationType,
  CommandTypes: () => CommandTypes,
  CompletionTriggerKind: () => CompletionTriggerKind,
  IndentStyle: () => IndentStyle2,
  JsxEmit: () => JsxEmit2,
  ModuleKind: () => ModuleKind2,
  ModuleResolutionKind: () => ModuleResolutionKind2,
  NewLineKind: () => NewLineKind2,
  OrganizeImportsMode: () => OrganizeImportsMode,
  PollingWatchKind: () => PollingWatchKind2,
  ScriptTarget: () => ScriptTarget11,
  SemicolonPreference: () => SemicolonPreference,
  WatchDirectoryKind: () => WatchDirectoryKind2,
  WatchFileKind: () => WatchFileKind2
});

// src/server/protocol.ts
var CommandTypes = /* @__PURE__ */ ((CommandTypes2) => {
  CommandTypes2["JsxClosingTag"] = "jsxClosingTag";
  CommandTypes2["LinkedEditingRange"] = "linkedEditingRange";
  CommandTypes2["Brace"] = "brace";
  CommandTypes2["BraceFull"] = "brace-full";
  CommandTypes2["BraceCompletion"] = "braceCompletion";
  CommandTypes2["GetSpanOfEnclosingComment"] = "getSpanOfEnclosingComment";
  CommandTypes2["Change"] = "change";
  CommandTypes2["Close"] = "close";
  CommandTypes2["Completions"] = "completions";
  CommandTypes2["CompletionInfo"] = "completionInfo";
  CommandTypes2["CompletionsFull"] = "completions-full";
  CommandTypes2["CompletionDetails"] = "completionEntryDetails";
  CommandTypes2["CompletionDetailsFull"] = "completionEntryDetails-full";
  CommandTypes2["CompileOnSaveAffectedFileList"] = "compileOnSaveAffectedFileList";
  CommandTypes2["CompileOnSaveEmitFile"] = "compileOnSaveEmitFile";
  CommandTypes2["Configure"] = "configure";
  CommandTypes2["Definition"] = "definition";
  CommandTypes2["DefinitionFull"] = "definition-full";
  CommandTypes2["DefinitionAndBoundSpan"] = "definitionAndBoundSpan";
  CommandTypes2["DefinitionAndBoundSpanFull"] = "definitionAndBoundSpan-full";
  CommandTypes2["Implementation"] = "implementation";
  CommandTypes2["ImplementationFull"] = "implementation-full";
  CommandTypes2["EmitOutput"] = "emit-output";
  CommandTypes2["Exit"] = "exit";
  CommandTypes2["FileReferences"] = "fileReferences";
  CommandTypes2["FileReferencesFull"] = "fileReferences-full";
  CommandTypes2["Format"] = "format";
  CommandTypes2["Formatonkey"] = "formatonkey";
  CommandTypes2["FormatFull"] = "format-full";
  CommandTypes2["FormatonkeyFull"] = "formatonkey-full";
  CommandTypes2["FormatRangeFull"] = "formatRange-full";
  CommandTypes2["Geterr"] = "geterr";
  CommandTypes2["GeterrForProject"] = "geterrForProject";
  CommandTypes2["SemanticDiagnosticsSync"] = "semanticDiagnosticsSync";
  CommandTypes2["SyntacticDiagnosticsSync"] = "syntacticDiagnosticsSync";
  CommandTypes2["SuggestionDiagnosticsSync"] = "suggestionDiagnosticsSync";
  CommandTypes2["NavBar"] = "navbar";
  CommandTypes2["NavBarFull"] = "navbar-full";
  CommandTypes2["Navto"] = "navto";
  CommandTypes2["NavtoFull"] = "navto-full";
  CommandTypes2["NavTree"] = "navtree";
  CommandTypes2["NavTreeFull"] = "navtree-full";
  CommandTypes2["DocumentHighlights"] = "documentHighlights";
  CommandTypes2["DocumentHighlightsFull"] = "documentHighlights-full";
  CommandTypes2["Open"] = "open";
  CommandTypes2["Quickinfo"] = "quickinfo";
  CommandTypes2["QuickinfoFull"] = "quickinfo-full";
  CommandTypes2["References"] = "references";
  CommandTypes2["ReferencesFull"] = "references-full";
  CommandTypes2["Reload"] = "reload";
  CommandTypes2["Rename"] = "rename";
  CommandTypes2["RenameInfoFull"] = "rename-full";
  CommandTypes2["RenameLocationsFull"] = "renameLocations-full";
  CommandTypes2["Saveto"] = "saveto";
  CommandTypes2["SignatureHelp"] = "signatureHelp";
  CommandTypes2["SignatureHelpFull"] = "signatureHelp-full";
  CommandTypes2["FindSourceDefinition"] = "findSourceDefinition";
  CommandTypes2["Status"] = "status";
  CommandTypes2["TypeDefinition"] = "typeDefinition";
  CommandTypes2["ProjectInfo"] = "projectInfo";
  CommandTypes2["ReloadProjects"] = "reloadProjects";
  CommandTypes2["Unknown"] = "unknown";
  CommandTypes2["OpenExternalProject"] = "openExternalProject";
  CommandTypes2["OpenExternalProjects"] = "openExternalProjects";
  CommandTypes2["CloseExternalProject"] = "closeExternalProject";
  CommandTypes2["SynchronizeProjectList"] = "synchronizeProjectList";
  CommandTypes2["ApplyChangedToOpenFiles"] = "applyChangedToOpenFiles";
  CommandTypes2["UpdateOpen"] = "updateOpen";
  CommandTypes2["EncodedSyntacticClassificationsFull"] = "encodedSyntacticClassifications-full";
  CommandTypes2["EncodedSemanticClassificationsFull"] = "encodedSemanticClassifications-full";
  CommandTypes2["Cleanup"] = "cleanup";
  CommandTypes2["GetOutliningSpans"] = "getOutliningSpans";
  CommandTypes2["GetOutliningSpansFull"] = "outliningSpans";
  CommandTypes2["TodoComments"] = "todoComments";
  CommandTypes2["Indentation"] = "indentation";
  CommandTypes2["DocCommentTemplate"] = "docCommentTemplate";
  CommandTypes2["CompilerOptionsDiagnosticsFull"] = "compilerOptionsDiagnostics-full";
  CommandTypes2["NameOrDottedNameSpan"] = "nameOrDottedNameSpan";
  CommandTypes2["BreakpointStatement"] = "breakpointStatement";
  CommandTypes2["CompilerOptionsForInferredProjects"] = "compilerOptionsForInferredProjects";
  CommandTypes2["GetCodeFixes"] = "getCodeFixes";
  CommandTypes2["GetCodeFixesFull"] = "getCodeFixes-full";
  CommandTypes2["GetCombinedCodeFix"] = "getCombinedCodeFix";
  CommandTypes2["GetCombinedCodeFixFull"] = "getCombinedCodeFix-full";
  CommandTypes2["ApplyCodeActionCommand"] = "applyCodeActionCommand";
  CommandTypes2["GetSupportedCodeFixes"] = "getSupportedCodeFixes";
  CommandTypes2["GetApplicableRefactors"] = "getApplicableRefactors";
  CommandTypes2["GetEditsForRefactor"] = "getEditsForRefactor";
  CommandTypes2["GetMoveToRefactoringFileSuggestions"] = "getMoveToRefactoringFileSuggestions";
  CommandTypes2["GetPasteEdits"] = "getPasteEdits";
  CommandTypes2["GetEditsForRefactorFull"] = "getEditsForRefactor-full";
  CommandTypes2["OrganizeImports"] = "organizeImports";
  CommandTypes2["OrganizeImportsFull"] = "organizeImports-full";
  CommandTypes2["GetEditsForFileRename"] = "getEditsForFileRename";
  CommandTypes2["GetEditsForFileRenameFull"] = "getEditsForFileRename-full";
  CommandTypes2["ConfigurePlugin"] = "configurePlugin";
  CommandTypes2["SelectionRange"] = "selectionRange";
  CommandTypes2["SelectionRangeFull"] = "selectionRange-full";
  CommandTypes2["ToggleLineComment"] = "toggleLineComment";
  CommandTypes2["ToggleLineCommentFull"] = "toggleLineComment-full";
  CommandTypes2["ToggleMultilineComment"] = "toggleMultilineComment";
  CommandTypes2["ToggleMultilineCommentFull"] = "toggleMultilineComment-full";
  CommandTypes2["CommentSelection"] = "commentSelection";
  CommandTypes2["CommentSelectionFull"] = "commentSelection-full";
  CommandTypes2["UncommentSelection"] = "uncommentSelection";
  CommandTypes2["UncommentSelectionFull"] = "uncommentSelection-full";
  CommandTypes2["PrepareCallHierarchy"] = "prepareCallHierarchy";
  CommandTypes2["ProvideCallHierarchyIncomingCalls"] = "provideCallHierarchyIncomingCalls";
  CommandTypes2["ProvideCallHierarchyOutgoingCalls"] = "provideCallHierarchyOutgoingCalls";
  CommandTypes2["ProvideInlayHints"] = "provideInlayHints";
  CommandTypes2["WatchChange"] = "watchChange";
  CommandTypes2["MapCode"] = "mapCode";
  return CommandTypes2;
})(CommandTypes || {});
var WatchFileKind2 = /* @__PURE__ */ ((WatchFileKind3) => {
  WatchFileKind3["FixedPollingInterval"] = "FixedPollingInterval";
  WatchFileKind3["PriorityPollingInterval"] = "PriorityPollingInterval";
  WatchFileKind3["DynamicPriorityPolling"] = "DynamicPriorityPolling";
  WatchFileKind3["FixedChunkSizePolling"] = "FixedChunkSizePolling";
  WatchFileKind3["UseFsEvents"] = "UseFsEvents";
  WatchFileKind3["UseFsEventsOnParentDirectory"] = "UseFsEventsOnParentDirectory";
  return WatchFileKind3;
})(WatchFileKind2 || {});
var WatchDirectoryKind2 = /* @__PURE__ */ ((WatchDirectoryKind3) => {
  WatchDirectoryKind3["UseFsEvents"] = "UseFsEvents";
  WatchDirectoryKind3["FixedPollingInterval"] = "FixedPollingInterval";
  WatchDirectoryKind3["DynamicPriorityPolling"] = "DynamicPriorityPolling";
  WatchDirectoryKind3["FixedChunkSizePolling"] = "FixedChunkSizePolling";
  return WatchDirectoryKind3;
})(WatchDirectoryKind2 || {});
var PollingWatchKind2 = /* @__PURE__ */ ((PollingWatchKind3) => {
  PollingWatchKind3["FixedInterval"] = "FixedInterval";
  PollingWatchKind3["PriorityInterval"] = "PriorityInterval";
  PollingWatchKind3["DynamicPriority"] = "DynamicPriority";
  PollingWatchKind3["FixedChunkSize"] = "FixedChunkSize";
  return PollingWatchKind3;
})(PollingWatchKind2 || {});
var IndentStyle2 = /* @__PURE__ */ ((IndentStyle3) => {
  IndentStyle3["None"] = "None";
  IndentStyle3["Block"] = "Block";
  IndentStyle3["Smart"] = "Smart";
  return IndentStyle3;
})(IndentStyle2 || {});
var JsxEmit2 = /* @__PURE__ */ ((JsxEmit3) => {
  JsxEmit3["None"] = "none";
  JsxEmit3["Preserve"] = "preserve";
  JsxEmit3["ReactNative"] = "react-native";
  JsxEmit3["React"] = "react";
  JsxEmit3["ReactJSX"] = "react-jsx";
  JsxEmit3["ReactJSXDev"] = "react-jsxdev";
  return JsxEmit3;
})(JsxEmit2 || {});
var ModuleKind2 = /* @__PURE__ */ ((ModuleKind3) => {
  ModuleKind3["None"] = "none";
  ModuleKind3["CommonJS"] = "commonjs";
  ModuleKind3["AMD"] = "amd";
  ModuleKind3["UMD"] = "umd";
  ModuleKind3["System"] = "system";
  ModuleKind3["ES6"] = "es6";
  ModuleKind3["ES2015"] = "es2015";
  ModuleKind3["ES2020"] = "es2020";
  ModuleKind3["ES2022"] = "es2022";
  ModuleKind3["ESNext"] = "esnext";
  ModuleKind3["Node16"] = "node16";
  ModuleKind3["NodeNext"] = "nodenext";
  ModuleKind3["Preserve"] = "preserve";
  return ModuleKind3;
})(ModuleKind2 || {});
var ModuleResolutionKind2 = /* @__PURE__ */ ((ModuleResolutionKind3) => {
  ModuleResolutionKind3["Classic"] = "classic";
  ModuleResolutionKind3["Node"] = "node";
  ModuleResolutionKind3["NodeJs"] = "node";
  ModuleResolutionKind3["Node10"] = "node10";
  ModuleResolutionKind3["Node16"] = "node16";
  ModuleResolutionKind3["NodeNext"] = "nodenext";
  ModuleResolutionKind3["Bundler"] = "bundler";
  return ModuleResolutionKind3;
})(ModuleResolutionKind2 || {});
var NewLineKind2 = /* @__PURE__ */ ((NewLineKind3) => {
  NewLineKind3["Crlf"] = "Crlf";
  NewLineKind3["Lf"] = "Lf";
  return NewLineKind3;
})(NewLineKind2 || {});
var ScriptTarget11 = /* @__PURE__ */ ((ScriptTarget12) => {
  ScriptTarget12["ES3"] = "es3";
  ScriptTarget12["ES5"] = "es5";
  ScriptTarget12["ES6"] = "es6";
  ScriptTarget12["ES2015"] = "es2015";
  ScriptTarget12["ES2016"] = "es2016";
  ScriptTarget12["ES2017"] = "es2017";
  ScriptTarget12["ES2018"] = "es2018";
  ScriptTarget12["ES2019"] = "es2019";
  ScriptTarget12["ES2020"] = "es2020";
  ScriptTarget12["ES2021"] = "es2021";
  ScriptTarget12["ES2022"] = "es2022";
  ScriptTarget12["ES2023"] = "es2023";
  ScriptTarget12["ESNext"] = "esnext";
  ScriptTarget12["JSON"] = "json";
  ScriptTarget12["Latest"] = "esnext" /* ESNext */;
  return ScriptTarget12;
})(ScriptTarget11 || {});
{
}

// src/server/scriptInfo.ts
var TextStorage = class {
  constructor(host, info, initialVersion) {
    this.host = host;
    this.info = info;
    /**
     * True if the text is for the file thats open in the editor
     */
    this.isOpen = false;
    /**
     * True if the text present is the text from the file on the disk
     */
    this.ownFileText = false;
    /**
     * True when reloading contents of file from the disk is pending
     */
    this.pendingReloadFromDisk = false;
    this.version = initialVersion || 0;
  }
  getVersion() {
    return this.svc ? `SVC-${this.version}-${this.svc.getSnapshotVersion()}` : `Text-${this.version}`;
  }
  hasScriptVersionCache_TestOnly() {
    return this.svc !== void 0;
  }
  resetSourceMapInfo() {
    this.info.sourceFileLike = void 0;
    this.info.closeSourceMapFileWatcher();
    this.info.sourceMapFilePath = void 0;
    this.info.declarationInfoPath = void 0;
    this.info.sourceInfos = void 0;
    this.info.documentPositionMapper = void 0;
  }
  /** Public for testing */
  useText(newText) {
    this.svc = void 0;
    this.text = newText;
    this.textSnapshot = void 0;
    this.lineMap = void 0;
    this.fileSize = void 0;
    this.resetSourceMapInfo();
    this.version++;
  }
  edit(start, end, newText) {
    this.switchToScriptVersionCache().edit(start, end - start, newText);
    this.ownFileText = false;
    this.text = void 0;
    this.textSnapshot = void 0;
    this.lineMap = void 0;
    this.fileSize = void 0;
    this.resetSourceMapInfo();
  }
  /**
   * Set the contents as newText
   * returns true if text changed
   */
  reload(newText) {
    Debug.assert(newText !== void 0);
    this.pendingReloadFromDisk = false;
    if (!this.text && this.svc) {
      this.text = getSnapshotText(this.svc.getSnapshot());
    }
    if (this.text !== newText) {
      this.useText(newText);
      this.ownFileText = false;
      return true;
    }
    return false;
  }
  /**
   * Reads the contents from tempFile(if supplied) or own file and sets it as contents
   * returns true if text changed
   */
  reloadWithFileText(tempFileName) {
    const { text: newText, fileSize } = tempFileName || !this.info.isDynamicOrHasMixedContent() ? this.getFileTextAndSize(tempFileName) : { text: "", fileSize: void 0 };
    const reloaded = this.reload(newText);
    this.fileSize = fileSize;
    this.ownFileText = !tempFileName || tempFileName === this.info.fileName;
    if (this.ownFileText && this.info.mTime === missingFileModifiedTime.getTime()) {
      this.info.mTime = (this.host.getModifiedTime(this.info.fileName) || missingFileModifiedTime).getTime();
    }
    return reloaded;
  }
  /**
   * Schedule reload from the disk if its not already scheduled and its not own text
   * returns true when scheduling reload
   */
  scheduleReloadIfNeeded() {
    return !this.pendingReloadFromDisk && !this.ownFileText ? this.pendingReloadFromDisk = true : false;
  }
  delayReloadFromFileIntoText() {
    this.pendingReloadFromDisk = true;
  }
  /**
   * For telemetry purposes, we would like to be able to report the size of the file.
   * However, we do not want telemetry to require extra file I/O so we report a size
   * that may be stale (e.g. may not reflect change made on disk since the last reload).
   * NB: Will read from disk if the file contents have never been loaded because
   * telemetry falsely indicating size 0 would be counter-productive.
   */
  getTelemetryFileSize() {
    return !!this.fileSize ? this.fileSize : !!this.text ? this.text.length : !!this.svc ? this.svc.getSnapshot().getLength() : this.getSnapshot().getLength();
  }
  getSnapshot() {
    var _a;
    return ((_a = this.tryUseScriptVersionCache()) == null ? void 0 : _a.getSnapshot()) || (this.textSnapshot ?? (this.textSnapshot = ScriptSnapshot.fromString(Debug.checkDefined(this.text))));
  }
  getAbsolutePositionAndLineText(oneBasedLine) {
    const svc = this.tryUseScriptVersionCache();
    if (svc) return svc.getAbsolutePositionAndLineText(oneBasedLine);
    const lineMap = this.getLineMap();
    return oneBasedLine <= lineMap.length ? {
      absolutePosition: lineMap[oneBasedLine - 1],
      lineText: this.text.substring(lineMap[oneBasedLine - 1], lineMap[oneBasedLine])
    } : {
      absolutePosition: this.text.length,
      lineText: void 0
    };
  }
  /**
   *  @param line 0 based index
   */
  lineToTextSpan(line) {
    const svc = this.tryUseScriptVersionCache();
    if (svc) return svc.lineToTextSpan(line);
    const lineMap = this.getLineMap();
    const start = lineMap[line];
    const end = line + 1 < lineMap.length ? lineMap[line + 1] : this.text.length;
    return createTextSpanFromBounds(start, end);
  }
  /**
   * @param line 1 based index
   * @param offset 1 based index
   */
  lineOffsetToPosition(line, offset, allowEdits) {
    const svc = this.tryUseScriptVersionCache();
    return svc ? svc.lineOffsetToPosition(line, offset) : computePositionOfLineAndCharacter(this.getLineMap(), line - 1, offset - 1, this.text, allowEdits);
  }
  positionToLineOffset(position) {
    const svc = this.tryUseScriptVersionCache();
    if (svc) return svc.positionToLineOffset(position);
    const { line, character } = computeLineAndCharacterOfPosition(this.getLineMap(), position);
    return { line: line + 1, offset: character + 1 };
  }
  getFileTextAndSize(tempFileName) {
    let text;
    const fileName = tempFileName || this.info.fileName;
    const getText = () => text === void 0 ? text = this.host.readFile(fileName) || "" : text;
    if (!hasTSFileExtension(this.info.fileName)) {
      const fileSize = this.host.getFileSize ? this.host.getFileSize(fileName) : getText().length;
      if (fileSize > maxFileSize) {
        Debug.assert(!!this.info.containingProjects.length);
        const service = this.info.containingProjects[0].projectService;
        service.logger.info(`Skipped loading contents of large file ${fileName} for info ${this.info.fileName}: fileSize: ${fileSize}`);
        this.info.containingProjects[0].projectService.sendLargeFileReferencedEvent(fileName, fileSize);
        return { text: "", fileSize };
      }
    }
    return { text: getText() };
  }
  /** @internal */
  switchToScriptVersionCache() {
    if (!this.svc || this.pendingReloadFromDisk) {
      this.svc = ScriptVersionCache.fromString(this.getOrLoadText());
      this.textSnapshot = void 0;
      this.version++;
    }
    return this.svc;
  }
  tryUseScriptVersionCache() {
    if (!this.svc || this.pendingReloadFromDisk) {
      this.getOrLoadText();
    }
    if (this.isOpen) {
      if (!this.svc && !this.textSnapshot) {
        this.svc = ScriptVersionCache.fromString(Debug.checkDefined(this.text));
        this.textSnapshot = void 0;
      }
      return this.svc;
    }
    return this.svc;
  }
  getOrLoadText() {
    if (this.text === void 0 || this.pendingReloadFromDisk) {
      Debug.assert(!this.svc || this.pendingReloadFromDisk, "ScriptVersionCache should not be set when reloading from disk");
      this.reloadWithFileText();
    }
    return this.text;
  }
  getLineMap() {
    Debug.assert(!this.svc, "ScriptVersionCache should not be set");
    return this.lineMap || (this.lineMap = computeLineStarts(Debug.checkDefined(this.text)));
  }
  getLineInfo() {
    const svc = this.tryUseScriptVersionCache();
    if (svc) {
      return {
        getLineCount: () => svc.getLineCount(),
        getLineText: (line) => svc.getAbsolutePositionAndLineText(line + 1).lineText
      };
    }
    const lineMap = this.getLineMap();
    return getLineInfo(this.text, lineMap);
  }
};
function isDynamicFileName(fileName) {
  return fileName[0] === "^" || (fileName.includes("walkThroughSnippet:/") || fileName.includes("untitled:/")) && getBaseFileName(fileName)[0] === "^" || fileName.includes(":^") && !fileName.includes(directorySeparator);
}
var ScriptInfo = class {
  constructor(host, fileName, scriptKind, hasMixedContent, path, initialVersion) {
    this.host = host;
    this.fileName = fileName;
    this.scriptKind = scriptKind;
    this.hasMixedContent = hasMixedContent;
    this.path = path;
    /**
     * All projects that include this file
     */
    this.containingProjects = [];
    this.isDynamic = isDynamicFileName(fileName);
    this.textStorage = new TextStorage(host, this, initialVersion);
    if (hasMixedContent || this.isDynamic) {
      this.realpath = this.path;
    }
    this.scriptKind = scriptKind ? scriptKind : getScriptKindFromFileName(fileName);
  }
  /** @internal */
  isDynamicOrHasMixedContent() {
    return this.hasMixedContent || this.isDynamic;
  }
  isScriptOpen() {
    return this.textStorage.isOpen;
  }
  open(newText) {
    this.textStorage.isOpen = true;
    if (newText !== void 0 && this.textStorage.reload(newText)) {
      this.markContainingProjectsAsDirty();
    }
  }
  close(fileExists = true) {
    this.textStorage.isOpen = false;
    if (fileExists && this.textStorage.scheduleReloadIfNeeded()) {
      this.markContainingProjectsAsDirty();
    }
  }
  getSnapshot() {
    return this.textStorage.getSnapshot();
  }
  ensureRealPath() {
    if (this.realpath === void 0) {
      this.realpath = this.path;
      if (this.host.realpath) {
        Debug.assert(!!this.containingProjects.length);
        const project = this.containingProjects[0];
        const realpath = this.host.realpath(this.path);
        if (realpath) {
          this.realpath = project.toPath(realpath);
          if (this.realpath !== this.path) {
            project.projectService.realpathToScriptInfos.add(this.realpath, this);
          }
        }
      }
    }
  }
  /** @internal */
  getRealpathIfDifferent() {
    return this.realpath && this.realpath !== this.path ? this.realpath : void 0;
  }
  /**
   * @internal
   * Does not compute realpath; uses precomputed result. Use `ensureRealPath`
   * first if a definite result is needed.
   */
  isSymlink() {
    return this.realpath && this.realpath !== this.path;
  }
  getFormatCodeSettings() {
    return this.formatSettings;
  }
  getPreferences() {
    return this.preferences;
  }
  attachToProject(project) {
    const isNew = !this.isAttached(project);
    if (isNew) {
      this.containingProjects.push(project);
      if (!project.getCompilerOptions().preserveSymlinks) {
        this.ensureRealPath();
      }
      project.onFileAddedOrRemoved(this.isSymlink());
    }
    return isNew;
  }
  isAttached(project) {
    switch (this.containingProjects.length) {
      case 0:
        return false;
      case 1:
        return this.containingProjects[0] === project;
      case 2:
        return this.containingProjects[0] === project || this.containingProjects[1] === project;
      default:
        return contains(this.containingProjects, project);
    }
  }
  detachFromProject(project) {
    switch (this.containingProjects.length) {
      case 0:
        return;
      case 1:
        if (this.containingProjects[0] === project) {
          project.onFileAddedOrRemoved(this.isSymlink());
          this.containingProjects.pop();
        }
        break;
      case 2:
        if (this.containingProjects[0] === project) {
          project.onFileAddedOrRemoved(this.isSymlink());
          this.containingProjects[0] = this.containingProjects.pop();
        } else if (this.containingProjects[1] === project) {
          project.onFileAddedOrRemoved(this.isSymlink());
          this.containingProjects.pop();
        }
        break;
      default:
        if (orderedRemoveItem(this.containingProjects, project)) {
          project.onFileAddedOrRemoved(this.isSymlink());
        }
        break;
    }
  }
  detachAllProjects() {
    for (const p of this.containingProjects) {
      if (isConfiguredProject(p)) {
        p.getCachedDirectoryStructureHost().addOrDeleteFile(this.fileName, this.path, 2 /* Deleted */);
      }
      const existingRoot = p.getRootFilesMap().get(this.path);
      p.removeFile(
        this,
        /*fileExists*/
        false,
        /*detachFromProject*/
        false
      );
      p.onFileAddedOrRemoved(this.isSymlink());
      if (existingRoot && !isInferredProject(p)) {
        p.addMissingFileRoot(existingRoot.fileName);
      }
    }
    clear(this.containingProjects);
  }
  getDefaultProject() {
    switch (this.containingProjects.length) {
      case 0:
        return Errors.ThrowNoProject();
      case 1:
        return isProjectDeferredClose(this.containingProjects[0]) || isBackgroundProject(this.containingProjects[0]) ? Errors.ThrowNoProject() : this.containingProjects[0];
      default:
        let firstConfiguredProject;
        let firstInferredProject;
        let firstNonSourceOfProjectReferenceRedirect;
        let defaultConfiguredProject;
        for (let index = 0; index < this.containingProjects.length; index++) {
          const project = this.containingProjects[index];
          if (isConfiguredProject(project)) {
            if (project.deferredClose) continue;
            if (!project.isSourceOfProjectReferenceRedirect(this.fileName)) {
              if (defaultConfiguredProject === void 0 && index !== this.containingProjects.length - 1) {
                defaultConfiguredProject = project.projectService.findDefaultConfiguredProject(this) || false;
              }
              if (defaultConfiguredProject === project) return project;
              if (!firstNonSourceOfProjectReferenceRedirect) firstNonSourceOfProjectReferenceRedirect = project;
            }
            if (!firstConfiguredProject) firstConfiguredProject = project;
          } else if (isExternalProject(project)) {
            return project;
          } else if (!firstInferredProject && isInferredProject(project)) {
            firstInferredProject = project;
          }
        }
        return (defaultConfiguredProject || firstNonSourceOfProjectReferenceRedirect || firstConfiguredProject || firstInferredProject) ?? Errors.ThrowNoProject();
    }
  }
  registerFileUpdate() {
    for (const p of this.containingProjects) {
      p.registerFileUpdate(this.path);
    }
  }
  setOptions(formatSettings, preferences) {
    if (formatSettings) {
      if (!this.formatSettings) {
        this.formatSettings = getDefaultFormatCodeSettings(this.host.newLine);
        assign(this.formatSettings, formatSettings);
      } else {
        this.formatSettings = { ...this.formatSettings, ...formatSettings };
      }
    }
    if (preferences) {
      if (!this.preferences) {
        this.preferences = emptyOptions;
      }
      this.preferences = { ...this.preferences, ...preferences };
    }
  }
  getLatestVersion() {
    this.textStorage.getSnapshot();
    return this.textStorage.getVersion();
  }
  saveTo(fileName) {
    this.host.writeFile(fileName, getSnapshotText(this.textStorage.getSnapshot()));
  }
  /** @internal */
  delayReloadNonMixedContentFile() {
    Debug.assert(!this.isDynamicOrHasMixedContent());
    this.textStorage.delayReloadFromFileIntoText();
    this.markContainingProjectsAsDirty();
  }
  reloadFromFile(tempFileName) {
    if (this.textStorage.reloadWithFileText(tempFileName)) {
      this.markContainingProjectsAsDirty();
      return true;
    }
    return false;
  }
  editContent(start, end, newText) {
    this.textStorage.edit(start, end, newText);
    this.markContainingProjectsAsDirty();
  }
  markContainingProjectsAsDirty() {
    for (const p of this.containingProjects) {
      p.markFileAsDirty(this.path);
    }
  }
  isOrphan() {
    return this.deferredDelete || !forEach(this.containingProjects, (p) => !p.isOrphan());
  }
  /** @internal */
  isContainedByBackgroundProject() {
    return some(
      this.containingProjects,
      isBackgroundProject
    );
  }
  /**
   *  @param line 1 based index
   */
  lineToTextSpan(line) {
    return this.textStorage.lineToTextSpan(line);
  }
  // eslint-disable-line @typescript-eslint/unified-signatures
  lineOffsetToPosition(line, offset, allowEdits) {
    return this.textStorage.lineOffsetToPosition(line, offset, allowEdits);
  }
  positionToLineOffset(position) {
    failIfInvalidPosition(position);
    const location = this.textStorage.positionToLineOffset(position);
    failIfInvalidLocation(location);
    return location;
  }
  isJavaScript() {
    return this.scriptKind === 1 /* JS */ || this.scriptKind === 2 /* JSX */;
  }
  /** @internal */
  closeSourceMapFileWatcher() {
    if (this.sourceMapFilePath && !isString(this.sourceMapFilePath)) {
      closeFileWatcherOf(this.sourceMapFilePath);
      this.sourceMapFilePath = void 0;
    }
  }
};
function failIfInvalidPosition(position) {
  Debug.assert(typeof position === "number", `Expected position ${position} to be a number.`);
  Debug.assert(position >= 0, `Expected position to be non-negative.`);
}
function failIfInvalidLocation(location) {
  Debug.assert(typeof location.line === "number", `Expected line ${location.line} to be a number.`);
  Debug.assert(typeof location.offset === "number", `Expected offset ${location.offset} to be a number.`);
  Debug.assert(location.line > 0, `Expected line to be non-${location.line === 0 ? "zero" : "negative"}`);
  Debug.assert(location.offset > 0, `Expected offset to be non-${location.offset === 0 ? "zero" : "negative"}`);
}

// src/server/project.ts
var ProjectKind = /* @__PURE__ */ ((ProjectKind2) => {
  ProjectKind2[ProjectKind2["Inferred"] = 0] = "Inferred";
  ProjectKind2[ProjectKind2["Configured"] = 1] = "Configured";
  ProjectKind2[ProjectKind2["External"] = 2] = "External";
  ProjectKind2[ProjectKind2["AutoImportProvider"] = 3] = "AutoImportProvider";
  ProjectKind2[ProjectKind2["Auxiliary"] = 4] = "Auxiliary";
  return ProjectKind2;
})(ProjectKind || {});
function countEachFileTypes(infos, includeSizes = false) {
  const result = {
    js: 0,
    jsSize: 0,
    jsx: 0,
    jsxSize: 0,
    ts: 0,
    tsSize: 0,
    tsx: 0,
    tsxSize: 0,
    dts: 0,
    dtsSize: 0,
    deferred: 0,
    deferredSize: 0
  };
  for (const info of infos) {
    const fileSize = includeSizes ? info.textStorage.getTelemetryFileSize() : 0;
    switch (info.scriptKind) {
      case 1 /* JS */:
        result.js += 1;
        result.jsSize += fileSize;
        break;
      case 2 /* JSX */:
        result.jsx += 1;
        result.jsxSize += fileSize;
        break;
      case 3 /* TS */:
        if (isDeclarationFileName(info.fileName)) {
          result.dts += 1;
          result.dtsSize += fileSize;
        } else {
          result.ts += 1;
          result.tsSize += fileSize;
        }
        break;
      case 4 /* TSX */:
        result.tsx += 1;
        result.tsxSize += fileSize;
        break;
      case 7 /* Deferred */:
        result.deferred += 1;
        result.deferredSize += fileSize;
        break;
    }
  }
  return result;
}
function hasOneOrMoreJsAndNoTsFiles(project) {
  const counts2 = countEachFileTypes(project.getScriptInfos());
  return counts2.js > 0 && counts2.ts === 0 && counts2.tsx === 0;
}
function allRootFilesAreJsOrDts(project) {
  const counts2 = countEachFileTypes(project.getRootScriptInfos());
  return counts2.ts === 0 && counts2.tsx === 0;
}
function allFilesAreJsOrDts(project) {
  const counts2 = countEachFileTypes(project.getScriptInfos());
  return counts2.ts === 0 && counts2.tsx === 0;
}
function hasNoTypeScriptSource(fileNames) {
  return !fileNames.some((fileName) => fileExtensionIs(fileName, ".ts" /* Ts */) && !isDeclarationFileName(fileName) || fileExtensionIs(fileName, ".tsx" /* Tsx */));
}
function isGeneratedFileWatcher(watch) {
  return watch.generatedFilePath !== void 0;
}
function setIsEqualTo(arr1, arr2) {
  if (arr1 === arr2) {
    return true;
  }
  if ((arr1 || emptyArray2).length === 0 && (arr2 || emptyArray2).length === 0) {
    return true;
  }
  const set = /* @__PURE__ */ new Map();
  let unique = 0;
  for (const v of arr1) {
    if (set.get(v) !== true) {
      set.set(v, true);
      unique++;
    }
  }
  for (const v of arr2) {
    const isSet = set.get(v);
    if (isSet === void 0) {
      return false;
    }
    if (isSet === true) {
      set.set(v, false);
      unique--;
    }
  }
  return unique === 0;
}
function typeAcquisitionChanged(opt1, opt2) {
  return opt1.enable !== opt2.enable || !setIsEqualTo(opt1.include, opt2.include) || !setIsEqualTo(opt1.exclude, opt2.exclude);
}
function compilerOptionsChanged(opt1, opt2) {
  return getAllowJSCompilerOption(opt1) !== getAllowJSCompilerOption(opt2);
}
function unresolvedImportsChanged(imports1, imports2) {
  if (imports1 === imports2) {
    return false;
  }
  return !arrayIsEqualTo(imports1, imports2);
}
var Project2 = class _Project {
  /** @internal */
  constructor(projectName, projectKind, projectService, documentRegistry, hasExplicitListOfFiles, lastFileExceededProgramSize, compilerOptions, compileOnSaveEnabled, watchOptions, directoryStructureHost, currentDirectory) {
    this.projectKind = projectKind;
    this.projectService = projectService;
    this.documentRegistry = documentRegistry;
    this.compilerOptions = compilerOptions;
    this.compileOnSaveEnabled = compileOnSaveEnabled;
    this.watchOptions = watchOptions;
    this.rootFilesMap = /* @__PURE__ */ new Map();
    /** @internal */
    this.plugins = [];
    /**
     * This is map from files to unresolved imports in it
     * Maop does not contain entries for files that do not have unresolved imports
     * This helps in containing the set of files to invalidate
     *
     * @internal
     */
    this.cachedUnresolvedImportsPerFile = /* @__PURE__ */ new Map();
    this.hasAddedorRemovedFiles = false;
    this.hasAddedOrRemovedSymlinks = false;
    /**
     * Last version that was reported.
     */
    this.lastReportedVersion = 0;
    /**
     * Current project's program version. (incremented everytime new program is created that is not complete reuse from the old one)
     * This property is changed in 'updateGraph' based on the set of files in program
     * @internal
     */
    this.projectProgramVersion = 0;
    /**
     * Current version of the project state. It is changed when:
     * - new root file was added/removed
     * - edit happen in some file that is currently included in the project.
     * This property is different from projectStructureVersion since in most cases edits don't affect set of files in the project
     * @internal
     */
    this.projectStateVersion = 0;
    this.isInitialLoadPending = returnFalse;
    /** @internal */
    this.dirty = false;
    /** @internal */
    this.typingFiles = emptyArray2;
    this.moduleSpecifierCache = createModuleSpecifierCache(this);
    /** @internal */
    this.createHash = maybeBind(this.projectService.host, this.projectService.host.createHash);
    /** @internal */
    this.globalCacheResolutionModuleName = ts_JsTyping_exports.nonRelativeModuleNameForTypingCache;
    /** @internal */
    this.updateFromProjectInProgress = false;
    this.projectName = projectName;
    this.directoryStructureHost = directoryStructureHost;
    this.currentDirectory = this.projectService.getNormalizedAbsolutePath(currentDirectory);
    this.getCanonicalFileName = this.projectService.toCanonicalFileName;
    this.jsDocParsingMode = this.projectService.jsDocParsingMode;
    this.cancellationToken = new ThrottledCancellationToken(this.projectService.cancellationToken, this.projectService.throttleWaitMilliseconds);
    if (!this.compilerOptions) {
      this.compilerOptions = getDefaultCompilerOptions2();
      this.compilerOptions.allowNonTsExtensions = true;
      this.compilerOptions.allowJs = true;
    } else if (hasExplicitListOfFiles || getAllowJSCompilerOption(this.compilerOptions) || this.projectService.hasDeferredExtension()) {
      this.compilerOptions.allowNonTsExtensions = true;
    }
    switch (projectService.serverMode) {
      case 0 /* Semantic */:
        this.languageServiceEnabled = true;
        break;
      case 1 /* PartialSemantic */:
        this.languageServiceEnabled = true;
        this.compilerOptions.noResolve = true;
        this.compilerOptions.types = [];
        break;
      case 2 /* Syntactic */:
        this.languageServiceEnabled = false;
        this.compilerOptions.noResolve = true;
        this.compilerOptions.types = [];
        break;
      default:
        Debug.assertNever(projectService.serverMode);
    }
    this.setInternalCompilerOptionsForEmittingJsFiles();
    const host = this.projectService.host;
    if (this.projectService.logger.loggingEnabled()) {
      this.trace = (s) => this.writeLog(s);
    } else if (host.trace) {
      this.trace = (s) => host.trace(s);
    }
    this.realpath = maybeBind(host, host.realpath);
    this.preferNonRecursiveWatch = this.projectService.canUseWatchEvents || host.preferNonRecursiveWatch;
    this.resolutionCache = createResolutionCache(
      this,
      this.currentDirectory,
      /*logChangesWhenResolvingModule*/
      true
    );
    this.languageService = createLanguageService(this, this.documentRegistry, this.projectService.serverMode);
    if (lastFileExceededProgramSize) {
      this.disableLanguageService(lastFileExceededProgramSize);
    }
    this.markAsDirty();
    if (!isBackgroundProject(this)) {
      this.projectService.pendingEnsureProjectForOpenFiles = true;
    }
    this.projectService.onProjectCreation(this);
  }
  /** @internal */
  getResolvedProjectReferenceToRedirect(_fileName) {
    return void 0;
  }
  isNonTsProject() {
    updateProjectIfDirty(this);
    return allFilesAreJsOrDts(this);
  }
  isJsOnlyProject() {
    updateProjectIfDirty(this);
    return hasOneOrMoreJsAndNoTsFiles(this);
  }
  static resolveModule(moduleName, initialDir, host, log) {
    return _Project.importServicePluginSync({ name: moduleName }, [initialDir], host, log).resolvedModule;
  }
  /** @internal */
  static importServicePluginSync(pluginConfigEntry, searchPaths, host, log) {
    Debug.assertIsDefined(host.require);
    let errorLogs;
    let resolvedModule;
    for (const initialDir of searchPaths) {
      const resolvedPath = normalizeSlashes(host.resolvePath(combinePaths(initialDir, "node_modules")));
      log(`Loading ${pluginConfigEntry.name} from ${initialDir} (resolved to ${resolvedPath})`);
      const result = host.require(resolvedPath, pluginConfigEntry.name);
      if (!result.error) {
        resolvedModule = result.module;
        break;
      }
      const err = result.error.stack || result.error.message || JSON.stringify(result.error);
      (errorLogs ?? (errorLogs = [])).push(`Failed to load module '${pluginConfigEntry.name}' from ${resolvedPath}: ${err}`);
    }
    return { pluginConfigEntry, resolvedModule, errorLogs };
  }
  /** @internal */
  static async importServicePluginAsync(pluginConfigEntry, searchPaths, host, log) {
    Debug.assertIsDefined(host.importPlugin);
    let errorLogs;
    let resolvedModule;
    for (const initialDir of searchPaths) {
      const resolvedPath = combinePaths(initialDir, "node_modules");
      log(`Dynamically importing ${pluginConfigEntry.name} from ${initialDir} (resolved to ${resolvedPath})`);
      let result;
      try {
        result = await host.importPlugin(resolvedPath, pluginConfigEntry.name);
      } catch (e) {
        result = { module: void 0, error: e };
      }
      if (!result.error) {
        resolvedModule = result.module;
        break;
      }
      const err = result.error.stack || result.error.message || JSON.stringify(result.error);
      (errorLogs ?? (errorLogs = [])).push(`Failed to dynamically import module '${pluginConfigEntry.name}' from ${resolvedPath}: ${err}`);
    }
    return { pluginConfigEntry, resolvedModule, errorLogs };
  }
  isKnownTypesPackageName(name) {
    return this.projectService.typingsInstaller.isKnownTypesPackageName(name);
  }
  installPackage(options) {
    return this.projectService.typingsInstaller.installPackage({ ...options, projectName: this.projectName, projectRootPath: this.toPath(this.currentDirectory) });
  }
  /** @internal */
  getGlobalTypingsCacheLocation() {
    return this.getGlobalCache();
  }
  /** @internal */
  getSymlinkCache() {
    if (!this.symlinks) {
      this.symlinks = createSymlinkCache(this.getCurrentDirectory(), this.getCanonicalFileName);
    }
    if (this.program && !this.symlinks.hasProcessedResolutions()) {
      this.symlinks.setSymlinksFromResolutions(
        this.program.forEachResolvedModule,
        this.program.forEachResolvedTypeReferenceDirective,
        this.program.getAutomaticTypeDirectiveResolutions()
      );
    }
    return this.symlinks;
  }
  // Method of LanguageServiceHost
  getCompilationSettings() {
    return this.compilerOptions;
  }
  // Method to support public API
  getCompilerOptions() {
    return this.getCompilationSettings();
  }
  getNewLine() {
    return this.projectService.host.newLine;
  }
  getProjectVersion() {
    return this.projectStateVersion.toString();
  }
  getProjectReferences() {
    return void 0;
  }
  getScriptFileNames() {
    if (!this.rootFilesMap.size) {
      return emptyArray;
    }
    let result;
    this.rootFilesMap.forEach((value) => {
      if (this.languageServiceEnabled || value.info && value.info.isScriptOpen()) {
        (result || (result = [])).push(value.fileName);
      }
    });
    return addRange(result, this.typingFiles) || emptyArray;
  }
  getOrCreateScriptInfoAndAttachToProject(fileName) {
    const scriptInfo = this.projectService.getOrCreateScriptInfoNotOpenedByClient(
      fileName,
      this.currentDirectory,
      this.directoryStructureHost,
      /*deferredDeleteOk*/
      false
    );
    if (scriptInfo) {
      const existingValue = this.rootFilesMap.get(scriptInfo.path);
      if (existingValue && existingValue.info !== scriptInfo) {
        existingValue.info = scriptInfo;
      }
      scriptInfo.attachToProject(this);
    }
    return scriptInfo;
  }
  getScriptKind(fileName) {
    const info = this.projectService.getScriptInfoForPath(this.toPath(fileName));
    return info && info.scriptKind;
  }
  getScriptVersion(filename) {
    const info = this.projectService.getOrCreateScriptInfoNotOpenedByClient(
      filename,
      this.currentDirectory,
      this.directoryStructureHost,
      /*deferredDeleteOk*/
      false
    );
    return info && info.getLatestVersion();
  }
  getScriptSnapshot(filename) {
    const scriptInfo = this.getOrCreateScriptInfoAndAttachToProject(filename);
    if (scriptInfo) {
      return scriptInfo.getSnapshot();
    }
  }
  getCancellationToken() {
    return this.cancellationToken;
  }
  getCurrentDirectory() {
    return this.currentDirectory;
  }
  getDefaultLibFileName() {
    const nodeModuleBinDir = getDirectoryPath(normalizePath(this.projectService.getExecutingFilePath()));
    return combinePaths(nodeModuleBinDir, getDefaultLibFileName(this.compilerOptions));
  }
  useCaseSensitiveFileNames() {
    return this.projectService.host.useCaseSensitiveFileNames;
  }
  readDirectory(path, extensions, exclude, include, depth) {
    return this.directoryStructureHost.readDirectory(path, extensions, exclude, include, depth);
  }
  readFile(fileName) {
    return this.projectService.host.readFile(fileName);
  }
  writeFile(fileName, content) {
    return this.projectService.host.writeFile(fileName, content);
  }
  fileExists(file) {
    const path = this.toPath(file);
    return !!this.projectService.getScriptInfoForPath(path) || !this.isWatchedMissingFile(path) && this.directoryStructureHost.fileExists(file);
  }
  /** @internal */
  resolveModuleNameLiterals(moduleLiterals, containingFile, redirectedReference, options, containingSourceFile, reusedNames) {
    return this.resolutionCache.resolveModuleNameLiterals(moduleLiterals, containingFile, redirectedReference, options, containingSourceFile, reusedNames);
  }
  /** @internal */
  getModuleResolutionCache() {
    return this.resolutionCache.getModuleResolutionCache();
  }
  /** @internal */
  resolveTypeReferenceDirectiveReferences(typeDirectiveReferences, containingFile, redirectedReference, options, containingSourceFile, reusedNames) {
    return this.resolutionCache.resolveTypeReferenceDirectiveReferences(
      typeDirectiveReferences,
      containingFile,
      redirectedReference,
      options,
      containingSourceFile,
      reusedNames
    );
  }
  /** @internal */
  resolveLibrary(libraryName, resolveFrom, options, libFileName) {
    return this.resolutionCache.resolveLibrary(libraryName, resolveFrom, options, libFileName);
  }
  directoryExists(path) {
    return this.directoryStructureHost.directoryExists(path);
  }
  getDirectories(path) {
    return this.directoryStructureHost.getDirectories(path);
  }
  /** @internal */
  getCachedDirectoryStructureHost() {
    return void 0;
  }
  /** @internal */
  toPath(fileName) {
    return toPath(fileName, this.currentDirectory, this.projectService.toCanonicalFileName);
  }
  /** @internal */
  watchDirectoryOfFailedLookupLocation(directory, cb, flags) {
    return this.projectService.watchFactory.watchDirectory(
      directory,
      cb,
      flags,
      this.projectService.getWatchOptions(this),
      WatchType.FailedLookupLocations,
      this
    );
  }
  /** @internal */
  watchAffectingFileLocation(file, cb) {
    return this.projectService.watchFactory.watchFile(
      file,
      cb,
      2e3 /* High */,
      this.projectService.getWatchOptions(this),
      WatchType.AffectingFileLocation,
      this
    );
  }
  /** @internal */
  clearInvalidateResolutionOfFailedLookupTimer() {
    return this.projectService.throttledOperations.cancel(`${this.getProjectName()}FailedLookupInvalidation`);
  }
  /** @internal */
  scheduleInvalidateResolutionsOfFailedLookupLocations() {
    this.projectService.throttledOperations.schedule(
      `${this.getProjectName()}FailedLookupInvalidation`,
      /*delay*/
      1e3,
      () => {
        if (this.resolutionCache.invalidateResolutionsOfFailedLookupLocations()) {
          this.projectService.delayUpdateProjectGraphAndEnsureProjectStructureForOpenFiles(this);
        }
      }
    );
  }
  /** @internal */
  invalidateResolutionsOfFailedLookupLocations() {
    if (this.clearInvalidateResolutionOfFailedLookupTimer() && this.resolutionCache.invalidateResolutionsOfFailedLookupLocations()) {
      this.markAsDirty();
      this.projectService.delayEnsureProjectForOpenFiles();
    }
  }
  /** @internal */
  onInvalidatedResolution() {
    this.projectService.delayUpdateProjectGraphAndEnsureProjectStructureForOpenFiles(this);
  }
  /** @internal */
  watchTypeRootsDirectory(directory, cb, flags) {
    return this.projectService.watchFactory.watchDirectory(
      directory,
      cb,
      flags,
      this.projectService.getWatchOptions(this),
      WatchType.TypeRoots,
      this
    );
  }
  /** @internal */
  hasChangedAutomaticTypeDirectiveNames() {
    return this.resolutionCache.hasChangedAutomaticTypeDirectiveNames();
  }
  /** @internal */
  onChangedAutomaticTypeDirectiveNames() {
    this.projectService.delayUpdateProjectGraphAndEnsureProjectStructureForOpenFiles(this);
  }
  /** @internal */
  getGlobalCache() {
    return this.getTypeAcquisition().enable ? this.projectService.typingsInstaller.globalTypingsCacheLocation : void 0;
  }
  /** @internal */
  fileIsOpen(filePath) {
    return this.projectService.openFiles.has(filePath);
  }
  /** @internal */
  writeLog(s) {
    this.projectService.logger.info(s);
  }
  log(s) {
    this.writeLog(s);
  }
  error(s) {
    this.projectService.logger.msg(s, "Err" /* Err */);
  }
  setInternalCompilerOptionsForEmittingJsFiles() {
    if (this.projectKind === 0 /* Inferred */ || this.projectKind === 2 /* External */) {
      this.compilerOptions.noEmitForJsFiles = true;
    }
  }
  /**
   * Get the errors that dont have any file name associated
   */
  getGlobalProjectErrors() {
    return filter(this.projectErrors, (diagnostic) => !diagnostic.file) || emptyArray2;
  }
  /**
   * Get all the project errors
   */
  getAllProjectErrors() {
    return this.projectErrors || emptyArray2;
  }
  setProjectErrors(projectErrors) {
    this.projectErrors = projectErrors;
  }
  getLanguageService(ensureSynchronized = true) {
    if (ensureSynchronized) {
      updateProjectIfDirty(this);
    }
    return this.languageService;
  }
  /** @internal */
  getSourceMapper() {
    return this.getLanguageService().getSourceMapper();
  }
  /** @internal */
  clearSourceMapperCache() {
    this.languageService.clearSourceMapperCache();
  }
  /** @internal */
  getDocumentPositionMapper(generatedFileName, sourceFileName) {
    return this.projectService.getDocumentPositionMapper(this, generatedFileName, sourceFileName);
  }
  /** @internal */
  getSourceFileLike(fileName) {
    return this.projectService.getSourceFileLike(fileName, this);
  }
  /** @internal */
  shouldEmitFile(scriptInfo) {
    return scriptInfo && !scriptInfo.isDynamicOrHasMixedContent() && !this.program.isSourceOfProjectReferenceRedirect(scriptInfo.path);
  }
  getCompileOnSaveAffectedFileList(scriptInfo) {
    if (!this.languageServiceEnabled) {
      return [];
    }
    updateProjectIfDirty(this);
    this.builderState = BuilderState.create(
      this.program,
      this.builderState,
      /*disableUseFileVersionAsSignature*/
      true
    );
    return mapDefined(
      BuilderState.getFilesAffectedBy(
        this.builderState,
        this.program,
        scriptInfo.path,
        this.cancellationToken,
        this.projectService.host
      ),
      (sourceFile) => this.shouldEmitFile(this.projectService.getScriptInfoForPath(sourceFile.path)) ? sourceFile.fileName : void 0
    );
  }
  /**
   * Returns true if emit was conducted
   */
  emitFile(scriptInfo, writeFile2) {
    if (!this.languageServiceEnabled || !this.shouldEmitFile(scriptInfo)) {
      return { emitSkipped: true, diagnostics: emptyArray2 };
    }
    const { emitSkipped, diagnostics, outputFiles } = this.getLanguageService().getEmitOutput(scriptInfo.fileName);
    if (!emitSkipped) {
      for (const outputFile of outputFiles) {
        const outputFileAbsoluteFileName = getNormalizedAbsolutePath(outputFile.name, this.currentDirectory);
        writeFile2(outputFileAbsoluteFileName, outputFile.text, outputFile.writeByteOrderMark);
      }
      if (this.builderState && getEmitDeclarations(this.compilerOptions)) {
        const dtsFiles = outputFiles.filter((f) => isDeclarationFileName(f.name));
        if (dtsFiles.length === 1) {
          const sourceFile = this.program.getSourceFile(scriptInfo.fileName);
          const signature = this.projectService.host.createHash ? this.projectService.host.createHash(dtsFiles[0].text) : generateDjb2Hash(dtsFiles[0].text);
          BuilderState.updateSignatureOfFile(this.builderState, signature, sourceFile.resolvedPath);
        }
      }
    }
    return { emitSkipped, diagnostics };
  }
  enableLanguageService() {
    if (this.languageServiceEnabled || this.projectService.serverMode === 2 /* Syntactic */) {
      return;
    }
    this.languageServiceEnabled = true;
    this.lastFileExceededProgramSize = void 0;
    this.projectService.onUpdateLanguageServiceStateForProject(
      this,
      /*languageServiceEnabled*/
      true
    );
  }
  /** @internal */
  cleanupProgram() {
    if (this.program) {
      for (const f of this.program.getSourceFiles()) {
        this.detachScriptInfoIfNotRoot(f.fileName);
      }
      this.program.forEachResolvedProjectReference((ref) => this.detachScriptInfoFromProject(ref.sourceFile.fileName));
      this.program = void 0;
    }
  }
  disableLanguageService(lastFileExceededProgramSize) {
    if (!this.languageServiceEnabled) {
      return;
    }
    Debug.assert(this.projectService.serverMode !== 2 /* Syntactic */);
    this.languageService.cleanupSemanticCache();
    this.languageServiceEnabled = false;
    this.cleanupProgram();
    this.lastFileExceededProgramSize = lastFileExceededProgramSize;
    this.builderState = void 0;
    if (this.autoImportProviderHost) {
      this.autoImportProviderHost.close();
    }
    this.autoImportProviderHost = void 0;
    this.resolutionCache.closeTypeRootsWatch();
    this.clearGeneratedFileWatch();
    this.projectService.verifyDocumentRegistry();
    this.projectService.onUpdateLanguageServiceStateForProject(
      this,
      /*languageServiceEnabled*/
      false
    );
  }
  getProjectName() {
    return this.projectName;
  }
  removeLocalTypingsFromTypeAcquisition(newTypeAcquisition) {
    if (!newTypeAcquisition.enable || !newTypeAcquisition.include) {
      return newTypeAcquisition;
    }
    return { ...newTypeAcquisition, include: this.removeExistingTypings(newTypeAcquisition.include) };
  }
  getExternalFiles(updateLevel) {
    return toSorted(flatMap(this.plugins, (plugin) => {
      if (typeof plugin.module.getExternalFiles !== "function") return;
      try {
        return plugin.module.getExternalFiles(this, updateLevel || 0 /* Update */);
      } catch (e) {
        this.projectService.logger.info(`A plugin threw an exception in getExternalFiles: ${e}`);
        if (e.stack) {
          this.projectService.logger.info(e.stack);
        }
      }
    }));
  }
  getSourceFile(path) {
    if (!this.program) {
      return void 0;
    }
    return this.program.getSourceFileByPath(path);
  }
  /** @internal */
  getSourceFileOrConfigFile(path) {
    const options = this.program.getCompilerOptions();
    return path === options.configFilePath ? options.configFile : this.getSourceFile(path);
  }
  close() {
    var _a;
    if (this.typingsCache) this.projectService.typingsInstaller.onProjectClosed(this);
    this.typingsCache = void 0;
    this.closeWatchingTypingLocations();
    this.cleanupProgram();
    forEach(this.externalFiles, (externalFile) => this.detachScriptInfoIfNotRoot(externalFile));
    this.rootFilesMap.forEach((root) => {
      var _a2;
      return (_a2 = root.info) == null ? void 0 : _a2.detachFromProject(this);
    });
    this.projectService.pendingEnsureProjectForOpenFiles = true;
    this.rootFilesMap = void 0;
    this.externalFiles = void 0;
    this.program = void 0;
    this.builderState = void 0;
    this.resolutionCache.clear();
    this.resolutionCache = void 0;
    this.cachedUnresolvedImportsPerFile = void 0;
    (_a = this.packageJsonWatches) == null ? void 0 : _a.forEach((watcher) => {
      watcher.projects.delete(this);
      watcher.close();
    });
    this.packageJsonWatches = void 0;
    this.moduleSpecifierCache.clear();
    this.moduleSpecifierCache = void 0;
    this.directoryStructureHost = void 0;
    this.exportMapCache = void 0;
    this.projectErrors = void 0;
    this.plugins.length = 0;
    if (this.missingFilesMap) {
      clearMap(this.missingFilesMap, closeFileWatcher);
      this.missingFilesMap = void 0;
    }
    this.clearGeneratedFileWatch();
    this.clearInvalidateResolutionOfFailedLookupTimer();
    if (this.autoImportProviderHost) {
      this.autoImportProviderHost.close();
    }
    this.autoImportProviderHost = void 0;
    if (this.noDtsResolutionProject) {
      this.noDtsResolutionProject.close();
    }
    this.noDtsResolutionProject = void 0;
    this.languageService.dispose();
    this.languageService = void 0;
  }
  detachScriptInfoIfNotRoot(uncheckedFilename) {
    const info = this.projectService.getScriptInfo(uncheckedFilename);
    if (info && !this.isRoot(info)) {
      info.detachFromProject(this);
    }
  }
  isClosed() {
    return this.rootFilesMap === void 0;
  }
  hasRoots() {
    var _a;
    return !!((_a = this.rootFilesMap) == null ? void 0 : _a.size);
  }
  /** @internal */
  isOrphan() {
    return false;
  }
  getRootFiles() {
    return this.rootFilesMap && arrayFrom(mapDefinedIterator(this.rootFilesMap.values(), (value) => {
      var _a;
      return (_a = value.info) == null ? void 0 : _a.fileName;
    }));
  }
  /** @internal */
  getRootFilesMap() {
    return this.rootFilesMap;
  }
  getRootScriptInfos() {
    return arrayFrom(mapDefinedIterator(this.rootFilesMap.values(), (value) => value.info));
  }
  getScriptInfos() {
    if (!this.languageServiceEnabled) {
      return this.getRootScriptInfos();
    }
    return map(this.program.getSourceFiles(), (sourceFile) => {
      const scriptInfo = this.projectService.getScriptInfoForPath(sourceFile.resolvedPath);
      Debug.assert(!!scriptInfo, "getScriptInfo", () => `scriptInfo for a file '${sourceFile.fileName}' Path: '${sourceFile.path}' / '${sourceFile.resolvedPath}' is missing.`);
      return scriptInfo;
    });
  }
  getExcludedFiles() {
    return emptyArray2;
  }
  getFileNames(excludeFilesFromExternalLibraries, excludeConfigFiles) {
    if (!this.program) {
      return [];
    }
    if (!this.languageServiceEnabled) {
      let rootFiles = this.getRootFiles();
      if (this.compilerOptions) {
        const defaultLibrary = getDefaultLibFilePath(this.compilerOptions);
        if (defaultLibrary) {
          (rootFiles || (rootFiles = [])).push(asNormalizedPath(defaultLibrary));
        }
      }
      return rootFiles;
    }
    const result = [];
    for (const f of this.program.getSourceFiles()) {
      if (excludeFilesFromExternalLibraries && this.program.isSourceFileFromExternalLibrary(f)) {
        continue;
      }
      result.push(asNormalizedPath(f.fileName));
    }
    if (!excludeConfigFiles) {
      const configFile = this.program.getCompilerOptions().configFile;
      if (configFile) {
        result.push(asNormalizedPath(configFile.fileName));
        if (configFile.extendedSourceFiles) {
          for (const f of configFile.extendedSourceFiles) {
            result.push(asNormalizedPath(f));
          }
        }
      }
    }
    return result;
  }
  /** @internal */
  getFileNamesWithRedirectInfo(includeProjectReferenceRedirectInfo) {
    return this.getFileNames().map((fileName) => ({
      fileName,
      isSourceOfProjectReferenceRedirect: includeProjectReferenceRedirectInfo && this.isSourceOfProjectReferenceRedirect(fileName)
    }));
  }
  hasConfigFile(configFilePath) {
    if (this.program && this.languageServiceEnabled) {
      const configFile = this.program.getCompilerOptions().configFile;
      if (configFile) {
        if (configFilePath === asNormalizedPath(configFile.fileName)) {
          return true;
        }
        if (configFile.extendedSourceFiles) {
          for (const f of configFile.extendedSourceFiles) {
            if (configFilePath === asNormalizedPath(f)) {
              return true;
            }
          }
        }
      }
    }
    return false;
  }
  containsScriptInfo(info) {
    if (this.isRoot(info)) return true;
    if (!this.program) return false;
    const file = this.program.getSourceFileByPath(info.path);
    return !!file && file.resolvedPath === info.path;
  }
  containsFile(filename, requireOpen) {
    const info = this.projectService.getScriptInfoForNormalizedPath(filename);
    if (info && (info.isScriptOpen() || !requireOpen)) {
      return this.containsScriptInfo(info);
    }
    return false;
  }
  isRoot(info) {
    var _a, _b;
    return ((_b = (_a = this.rootFilesMap) == null ? void 0 : _a.get(info.path)) == null ? void 0 : _b.info) === info;
  }
  // add a root file to project
  addRoot(info, fileName) {
    Debug.assert(!this.isRoot(info));
    this.rootFilesMap.set(info.path, { fileName: fileName || info.fileName, info });
    info.attachToProject(this);
    this.markAsDirty();
  }
  // add a root file that doesnt exist on host
  addMissingFileRoot(fileName) {
    const path = this.projectService.toPath(fileName);
    this.rootFilesMap.set(path, { fileName });
    this.markAsDirty();
  }
  removeFile(info, fileExists, detachFromProject) {
    if (this.isRoot(info)) {
      this.removeRoot(info);
    }
    if (fileExists) {
      this.resolutionCache.removeResolutionsOfFile(info.path);
    } else {
      this.resolutionCache.invalidateResolutionOfFile(info.path);
    }
    this.cachedUnresolvedImportsPerFile.delete(info.path);
    if (detachFromProject) {
      info.detachFromProject(this);
    }
    this.markAsDirty();
  }
  registerFileUpdate(fileName) {
    (this.updatedFileNames || (this.updatedFileNames = /* @__PURE__ */ new Set())).add(fileName);
  }
  /** @internal */
  markFileAsDirty(changedFile) {
    this.markAsDirty();
    if (this.exportMapCache && !this.exportMapCache.isEmpty()) {
      (this.changedFilesForExportMapCache || (this.changedFilesForExportMapCache = /* @__PURE__ */ new Set())).add(changedFile);
    }
  }
  /** @internal */
  markAsDirty() {
    if (!this.dirty) {
      this.projectStateVersion++;
      this.dirty = true;
    }
  }
  /** @internal */
  markAutoImportProviderAsDirty() {
    var _a;
    if (!this.autoImportProviderHost) this.autoImportProviderHost = void 0;
    (_a = this.autoImportProviderHost) == null ? void 0 : _a.markAsDirty();
  }
  /** @internal */
  onAutoImportProviderSettingsChanged() {
    var _a;
    if (this.autoImportProviderHost === false) {
      this.autoImportProviderHost = void 0;
    } else {
      (_a = this.autoImportProviderHost) == null ? void 0 : _a.markAsDirty();
    }
  }
  /** @internal */
  onPackageJsonChange() {
    this.moduleSpecifierCache.clear();
    if (this.autoImportProviderHost) {
      this.autoImportProviderHost.markAsDirty();
    }
  }
  /** @internal */
  onFileAddedOrRemoved(isSymlink) {
    this.hasAddedorRemovedFiles = true;
    if (isSymlink) {
      this.hasAddedOrRemovedSymlinks = true;
    }
  }
  /** @internal */
  onDiscoveredSymlink() {
    this.hasAddedOrRemovedSymlinks = true;
  }
  /** @internal */
  onReleaseOldSourceFile(oldSourceFile, _oldOptions, hasSourceFileByPath, newSourceFileByResolvedPath) {
    if (!newSourceFileByResolvedPath || oldSourceFile.resolvedPath === oldSourceFile.path && newSourceFileByResolvedPath.resolvedPath !== oldSourceFile.path) {
      this.detachScriptInfoFromProject(oldSourceFile.fileName, hasSourceFileByPath);
    }
  }
  /** @internal */
  updateFromProject() {
    updateProjectIfDirty(this);
  }
  /**
   * Updates set of files that contribute to this project
   * @returns: true if set of files in the project stays the same and false - otherwise.
   */
  updateGraph() {
    var _a, _b;
    (_a = tracing) == null ? void 0 : _a.push(tracing.Phase.Session, "updateGraph", { name: this.projectName, kind: ProjectKind[this.projectKind] });
    this.resolutionCache.startRecordingFilesWithChangedResolutions();
    const hasNewProgram = this.updateGraphWorker();
    const hasAddedorRemovedFiles = this.hasAddedorRemovedFiles;
    this.hasAddedorRemovedFiles = false;
    this.hasAddedOrRemovedSymlinks = false;
    const changedFiles = this.resolutionCache.finishRecordingFilesWithChangedResolutions() || emptyArray2;
    for (const file of changedFiles) {
      this.cachedUnresolvedImportsPerFile.delete(file);
    }
    if (this.languageServiceEnabled && this.projectService.serverMode === 0 /* Semantic */ && !this.isOrphan()) {
      if (hasNewProgram || changedFiles.length) {
        this.lastCachedUnresolvedImportsList = getUnresolvedImports(this.program, this.cachedUnresolvedImportsPerFile);
      }
      this.enqueueInstallTypingsForProject(hasAddedorRemovedFiles);
    } else {
      this.lastCachedUnresolvedImportsList = void 0;
    }
    const isFirstProgramLoad = this.projectProgramVersion === 0 && hasNewProgram;
    if (hasNewProgram) {
      this.projectProgramVersion++;
    }
    if (hasAddedorRemovedFiles) {
      this.markAutoImportProviderAsDirty();
    }
    if (isFirstProgramLoad) {
      this.getPackageJsonAutoImportProvider();
    }
    (_b = tracing) == null ? void 0 : _b.pop();
    return !hasNewProgram;
  }
  /** @internal */
  enqueueInstallTypingsForProject(forceRefresh) {
    const typeAcquisition = this.getTypeAcquisition();
    if (!typeAcquisition || !typeAcquisition.enable || this.projectService.typingsInstaller === nullTypingsInstaller) {
      return;
    }
    const entry = this.typingsCache;
    if (forceRefresh || !entry || typeAcquisitionChanged(typeAcquisition, entry.typeAcquisition) || compilerOptionsChanged(this.getCompilationSettings(), entry.compilerOptions) || unresolvedImportsChanged(this.lastCachedUnresolvedImportsList, entry.unresolvedImports)) {
      this.typingsCache = {
        compilerOptions: this.getCompilationSettings(),
        typeAcquisition,
        unresolvedImports: this.lastCachedUnresolvedImportsList
      };
      this.projectService.typingsInstaller.enqueueInstallTypingsRequest(this, typeAcquisition, this.lastCachedUnresolvedImportsList);
    }
  }
  /** @internal */
  updateTypingFiles(compilerOptions, typeAcquisition, unresolvedImports, newTypings) {
    this.typingsCache = {
      compilerOptions,
      typeAcquisition,
      unresolvedImports
    };
    const typingFiles = !typeAcquisition || !typeAcquisition.enable ? emptyArray2 : toSorted(newTypings);
    if (enumerateInsertsAndDeletes(
      typingFiles,
      this.typingFiles,
      getStringComparer(!this.useCaseSensitiveFileNames()),
      /*inserted*/
      noop,
      (removed) => this.detachScriptInfoFromProject(removed)
    )) {
      this.typingFiles = typingFiles;
      this.resolutionCache.setFilesWithInvalidatedNonRelativeUnresolvedImports(this.cachedUnresolvedImportsPerFile);
      this.projectService.delayUpdateProjectGraphAndEnsureProjectStructureForOpenFiles(this);
    }
  }
  closeWatchingTypingLocations() {
    if (this.typingWatchers) clearMap(this.typingWatchers, closeFileWatcher);
    this.typingWatchers = void 0;
  }
  onTypingInstallerWatchInvoke() {
    this.typingWatchers.isInvoked = true;
    this.projectService.updateTypingsForProject({ projectName: this.getProjectName(), kind: ActionInvalidate });
  }
  /** @internal */
  watchTypingLocations(files) {
    if (!files) {
      this.typingWatchers.isInvoked = false;
      return;
    }
    if (!files.length) {
      this.closeWatchingTypingLocations();
      return;
    }
    const toRemove = new Map(this.typingWatchers);
    if (!this.typingWatchers) this.typingWatchers = /* @__PURE__ */ new Map();
    this.typingWatchers.isInvoked = false;
    const createProjectWatcher = (path, typingsWatcherType) => {
      const canonicalPath = this.toPath(path);
      toRemove.delete(canonicalPath);
      if (!this.typingWatchers.has(canonicalPath)) {
        this.typingWatchers.set(
          canonicalPath,
          typingsWatcherType === "FileWatcher" /* FileWatcher */ ? this.projectService.watchFactory.watchFile(
            path,
            () => !this.typingWatchers.isInvoked ? this.onTypingInstallerWatchInvoke() : this.writeLog(`TypingWatchers already invoked`),
            2e3 /* High */,
            this.projectService.getWatchOptions(this),
            WatchType.TypingInstallerLocationFile,
            this
          ) : this.projectService.watchFactory.watchDirectory(
            path,
            (f) => {
              if (this.typingWatchers.isInvoked) return this.writeLog(`TypingWatchers already invoked`);
              if (!fileExtensionIs(f, ".json" /* Json */)) return this.writeLog(`Ignoring files that are not *.json`);
              if (comparePaths(f, combinePaths(this.projectService.typingsInstaller.globalTypingsCacheLocation, "package.json"), !this.useCaseSensitiveFileNames())) return this.writeLog(`Ignoring package.json change at global typings location`);
              this.onTypingInstallerWatchInvoke();
            },
            1 /* Recursive */,
            this.projectService.getWatchOptions(this),
            WatchType.TypingInstallerLocationDirectory,
            this
          )
        );
      }
    };
    for (const file of files) {
      const basename = getBaseFileName(file);
      if (basename === "package.json" || basename === "bower.json") {
        createProjectWatcher(file, "FileWatcher" /* FileWatcher */);
        continue;
      }
      if (containsPath(this.currentDirectory, file, this.currentDirectory, !this.useCaseSensitiveFileNames())) {
        const subDirectory = file.indexOf(directorySeparator, this.currentDirectory.length + 1);
        if (subDirectory !== -1) {
          createProjectWatcher(file.substr(0, subDirectory), "DirectoryWatcher" /* DirectoryWatcher */);
        } else {
          createProjectWatcher(file, "DirectoryWatcher" /* DirectoryWatcher */);
        }
        continue;
      }
      if (containsPath(this.projectService.typingsInstaller.globalTypingsCacheLocation, file, this.currentDirectory, !this.useCaseSensitiveFileNames())) {
        createProjectWatcher(this.projectService.typingsInstaller.globalTypingsCacheLocation, "DirectoryWatcher" /* DirectoryWatcher */);
        continue;
      }
      createProjectWatcher(file, "DirectoryWatcher" /* DirectoryWatcher */);
    }
    toRemove.forEach((watch, path) => {
      watch.close();
      this.typingWatchers.delete(path);
    });
  }
  /** @internal */
  getCurrentProgram() {
    return this.program;
  }
  removeExistingTypings(include) {
    if (!include.length) return include;
    const existing = getAutomaticTypeDirectiveNames(this.getCompilerOptions(), this.directoryStructureHost);
    return filter(include, (i) => !existing.includes(i));
  }
  updateGraphWorker() {
    var _a, _b;
    const oldProgram = this.languageService.getCurrentProgram();
    Debug.assert(oldProgram === this.program);
    Debug.assert(!this.isClosed(), "Called update graph worker of closed project");
    this.writeLog(`Starting updateGraphWorker: Project: ${this.getProjectName()}`);
    const start = timestamp();
    const { hasInvalidatedResolutions, hasInvalidatedLibResolutions } = this.resolutionCache.createHasInvalidatedResolutions(returnFalse, returnFalse);
    this.hasInvalidatedResolutions = hasInvalidatedResolutions;
    this.hasInvalidatedLibResolutions = hasInvalidatedLibResolutions;
    this.resolutionCache.startCachingPerDirectoryResolution();
    this.dirty = false;
    this.updateFromProjectInProgress = true;
    this.program = this.languageService.getProgram();
    this.updateFromProjectInProgress = false;
    (_a = tracing) == null ? void 0 : _a.push(tracing.Phase.Session, "finishCachingPerDirectoryResolution");
    this.resolutionCache.finishCachingPerDirectoryResolution(this.program, oldProgram);
    (_b = tracing) == null ? void 0 : _b.pop();
    Debug.assert(oldProgram === void 0 || this.program !== void 0);
    let hasNewProgram = false;
    if (this.program && (!oldProgram || this.program !== oldProgram && this.program.structureIsReused !== 2 /* Completely */)) {
      hasNewProgram = true;
      this.rootFilesMap.forEach((value, path) => {
        var _a2;
        const file = this.program.getSourceFileByPath(path);
        const info = value.info;
        if (!file || ((_a2 = value.info) == null ? void 0 : _a2.path) === file.resolvedPath) return;
        value.info = this.projectService.getScriptInfo(file.fileName);
        Debug.assert(value.info.isAttached(this));
        info == null ? void 0 : info.detachFromProject(this);
      });
      updateMissingFilePathsWatch(
        this.program,
        this.missingFilesMap || (this.missingFilesMap = /* @__PURE__ */ new Map()),
        // Watch the missing files
        (missingFilePath, missingFileName) => this.addMissingFileWatcher(missingFilePath, missingFileName)
      );
      if (this.generatedFilesMap) {
        const outPath = this.compilerOptions.outFile;
        if (isGeneratedFileWatcher(this.generatedFilesMap)) {
          if (!outPath || !this.isValidGeneratedFileWatcher(
            removeFileExtension(outPath) + ".d.ts" /* Dts */,
            this.generatedFilesMap
          )) {
            this.clearGeneratedFileWatch();
          }
        } else {
          if (outPath) {
            this.clearGeneratedFileWatch();
          } else {
            this.generatedFilesMap.forEach((watcher, source) => {
              const sourceFile = this.program.getSourceFileByPath(source);
              if (!sourceFile || sourceFile.resolvedPath !== source || !this.isValidGeneratedFileWatcher(
                getDeclarationEmitOutputFilePathWorker(sourceFile.fileName, this.compilerOptions, this.program),
                watcher
              )) {
                closeFileWatcherOf(watcher);
                this.generatedFilesMap.delete(source);
              }
            });
          }
        }
      }
      if (this.languageServiceEnabled && this.projectService.serverMode === 0 /* Semantic */) {
        this.resolutionCache.updateTypeRootsWatch();
      }
    }
    this.projectService.verifyProgram(this);
    if (this.exportMapCache && !this.exportMapCache.isEmpty()) {
      this.exportMapCache.releaseSymbols();
      if (this.hasAddedorRemovedFiles || oldProgram && !this.program.structureIsReused) {
        this.exportMapCache.clear();
      } else if (this.changedFilesForExportMapCache && oldProgram && this.program) {
        forEachKey(this.changedFilesForExportMapCache, (fileName) => {
          const oldSourceFile = oldProgram.getSourceFileByPath(fileName);
          const sourceFile = this.program.getSourceFileByPath(fileName);
          if (!oldSourceFile || !sourceFile) {
            this.exportMapCache.clear();
            return true;
          }
          return this.exportMapCache.onFileChanged(oldSourceFile, sourceFile, !!this.getTypeAcquisition().enable);
        });
      }
    }
    if (this.changedFilesForExportMapCache) {
      this.changedFilesForExportMapCache.clear();
    }
    if (this.hasAddedOrRemovedSymlinks || this.program && !this.program.structureIsReused && this.getCompilerOptions().preserveSymlinks) {
      this.symlinks = void 0;
      this.moduleSpecifierCache.clear();
    }
    const oldExternalFiles = this.externalFiles || emptyArray2;
    this.externalFiles = this.getExternalFiles();
    enumerateInsertsAndDeletes(
      this.externalFiles,
      oldExternalFiles,
      getStringComparer(!this.useCaseSensitiveFileNames()),
      // Ensure a ScriptInfo is created for new external files. This is performed indirectly
      // by the host for files in the program when the program is retrieved above but
      // the program doesn't contain external files so this must be done explicitly.
      (inserted) => {
        const scriptInfo = this.projectService.getOrCreateScriptInfoNotOpenedByClient(
          inserted,
          this.currentDirectory,
          this.directoryStructureHost,
          /*deferredDeleteOk*/
          false
        );
        scriptInfo == null ? void 0 : scriptInfo.attachToProject(this);
      },
      (removed) => this.detachScriptInfoFromProject(removed)
    );
    const elapsed = timestamp() - start;
    this.sendPerformanceEvent("UpdateGraph", elapsed);
    this.writeLog(`Finishing updateGraphWorker: Project: ${this.getProjectName()} projectStateVersion: ${this.projectStateVersion} projectProgramVersion: ${this.projectProgramVersion} structureChanged: ${hasNewProgram}${this.program ? ` structureIsReused:: ${StructureIsReused[this.program.structureIsReused]}` : ""} Elapsed: ${elapsed}ms`);
    if (this.projectService.logger.isTestLogger) {
      if (this.program !== oldProgram) {
        this.print(
          /*writeProjectFileNames*/
          true,
          this.hasAddedorRemovedFiles,
          /*writeFileVersionAndText*/
          true
        );
      } else {
        this.writeLog(`Same program as before`);
      }
    } else if (this.hasAddedorRemovedFiles) {
      this.print(
        /*writeProjectFileNames*/
        true,
        /*writeFileExplaination*/
        true,
        /*writeFileVersionAndText*/
        false
      );
    } else if (this.program !== oldProgram) {
      this.writeLog(`Different program with same set of files`);
    }
    this.projectService.verifyDocumentRegistry();
    return hasNewProgram;
  }
  /** @internal */
  sendPerformanceEvent(kind, durationMs) {
    this.projectService.sendPerformanceEvent(kind, durationMs);
  }
  detachScriptInfoFromProject(uncheckedFileName, noRemoveResolution) {
    const scriptInfoToDetach = this.projectService.getScriptInfo(uncheckedFileName);
    if (scriptInfoToDetach) {
      scriptInfoToDetach.detachFromProject(this);
      if (!noRemoveResolution) {
        this.resolutionCache.removeResolutionsOfFile(scriptInfoToDetach.path);
      }
    }
  }
  addMissingFileWatcher(missingFilePath, missingFileName) {
    var _a;
    if (isConfiguredProject(this)) {
      const configFileExistenceInfo = this.projectService.configFileExistenceInfoCache.get(missingFilePath);
      if ((_a = configFileExistenceInfo == null ? void 0 : configFileExistenceInfo.config) == null ? void 0 : _a.projects.has(this.canonicalConfigFilePath)) return noopFileWatcher;
    }
    const fileWatcher = this.projectService.watchFactory.watchFile(
      getNormalizedAbsolutePath(missingFileName, this.currentDirectory),
      (fileName, eventKind) => {
        if (isConfiguredProject(this)) {
          this.getCachedDirectoryStructureHost().addOrDeleteFile(fileName, missingFilePath, eventKind);
        }
        if (eventKind === 0 /* Created */ && this.missingFilesMap.has(missingFilePath)) {
          this.missingFilesMap.delete(missingFilePath);
          fileWatcher.close();
          this.projectService.delayUpdateProjectGraphAndEnsureProjectStructureForOpenFiles(this);
        }
      },
      500 /* Medium */,
      this.projectService.getWatchOptions(this),
      WatchType.MissingFile,
      this
    );
    return fileWatcher;
  }
  isWatchedMissingFile(path) {
    return !!this.missingFilesMap && this.missingFilesMap.has(path);
  }
  /** @internal */
  addGeneratedFileWatch(generatedFile, sourceFile) {
    if (this.compilerOptions.outFile) {
      if (!this.generatedFilesMap) {
        this.generatedFilesMap = this.createGeneratedFileWatcher(generatedFile);
      }
    } else {
      const path = this.toPath(sourceFile);
      if (this.generatedFilesMap) {
        if (isGeneratedFileWatcher(this.generatedFilesMap)) {
          Debug.fail(`${this.projectName} Expected to not have --out watcher for generated file with options: ${JSON.stringify(this.compilerOptions)}`);
          return;
        }
        if (this.generatedFilesMap.has(path)) return;
      } else {
        this.generatedFilesMap = /* @__PURE__ */ new Map();
      }
      this.generatedFilesMap.set(path, this.createGeneratedFileWatcher(generatedFile));
    }
  }
  createGeneratedFileWatcher(generatedFile) {
    return {
      generatedFilePath: this.toPath(generatedFile),
      watcher: this.projectService.watchFactory.watchFile(
        generatedFile,
        () => {
          this.clearSourceMapperCache();
          this.projectService.delayUpdateProjectGraphAndEnsureProjectStructureForOpenFiles(this);
        },
        2e3 /* High */,
        this.projectService.getWatchOptions(this),
        WatchType.MissingGeneratedFile,
        this
      )
    };
  }
  isValidGeneratedFileWatcher(generateFile, watcher) {
    return this.toPath(generateFile) === watcher.generatedFilePath;
  }
  clearGeneratedFileWatch() {
    if (this.generatedFilesMap) {
      if (isGeneratedFileWatcher(this.generatedFilesMap)) {
        closeFileWatcherOf(this.generatedFilesMap);
      } else {
        clearMap(this.generatedFilesMap, closeFileWatcherOf);
      }
      this.generatedFilesMap = void 0;
    }
  }
  getScriptInfoForNormalizedPath(fileName) {
    const scriptInfo = this.projectService.getScriptInfoForPath(this.toPath(fileName));
    if (scriptInfo && !scriptInfo.isAttached(this)) {
      return Errors.ThrowProjectDoesNotContainDocument(fileName, this);
    }
    return scriptInfo;
  }
  getScriptInfo(uncheckedFileName) {
    return this.projectService.getScriptInfo(uncheckedFileName);
  }
  filesToString(writeProjectFileNames) {
    return this.filesToStringWorker(
      writeProjectFileNames,
      /*writeFileExplaination*/
      true,
      /*writeFileVersionAndText*/
      false
    );
  }
  filesToStringWorker(writeProjectFileNames, writeFileExplaination, writeFileVersionAndText) {
    if (this.isInitialLoadPending()) return "	Files (0) InitialLoadPending\n";
    if (!this.program) return "	Files (0) NoProgram\n";
    const sourceFiles = this.program.getSourceFiles();
    let strBuilder = `	Files (${sourceFiles.length})
`;
    if (writeProjectFileNames) {
      for (const file of sourceFiles) {
        strBuilder += `	${file.fileName}${writeFileVersionAndText ? ` ${file.version} ${JSON.stringify(file.text)}` : ""}
`;
      }
      if (writeFileExplaination) {
        strBuilder += "\n\n";
        explainFiles(this.program, (s) => strBuilder += `	${s}
`);
      }
    }
    return strBuilder;
  }
  /** @internal */
  print(writeProjectFileNames, writeFileExplaination, writeFileVersionAndText) {
    var _a;
    this.writeLog(`Project '${this.projectName}' (${ProjectKind[this.projectKind]})`);
    this.writeLog(this.filesToStringWorker(
      writeProjectFileNames && this.projectService.logger.hasLevel(3 /* verbose */),
      writeFileExplaination && this.projectService.logger.hasLevel(3 /* verbose */),
      writeFileVersionAndText && this.projectService.logger.hasLevel(3 /* verbose */)
    ));
    this.writeLog("-----------------------------------------------");
    if (this.autoImportProviderHost) {
      this.autoImportProviderHost.print(
        /*writeProjectFileNames*/
        false,
        /*writeFileExplaination*/
        false,
        /*writeFileVersionAndText*/
        false
      );
    }
    (_a = this.noDtsResolutionProject) == null ? void 0 : _a.print(
      /*writeProjectFileNames*/
      false,
      /*writeFileExplaination*/
      false,
      /*writeFileVersionAndText*/
      false
    );
  }
  setCompilerOptions(compilerOptions) {
    var _a;
    if (compilerOptions) {
      compilerOptions.allowNonTsExtensions = true;
      const oldOptions = this.compilerOptions;
      this.compilerOptions = compilerOptions;
      this.setInternalCompilerOptionsForEmittingJsFiles();
      (_a = this.noDtsResolutionProject) == null ? void 0 : _a.setCompilerOptions(this.getCompilerOptionsForNoDtsResolutionProject());
      if (changesAffectModuleResolution(oldOptions, compilerOptions)) {
        this.cachedUnresolvedImportsPerFile.clear();
        this.lastCachedUnresolvedImportsList = void 0;
        this.resolutionCache.onChangesAffectModuleResolution();
        this.moduleSpecifierCache.clear();
      }
      this.markAsDirty();
    }
  }
  /** @internal */
  setWatchOptions(watchOptions) {
    this.watchOptions = watchOptions;
  }
  /** @internal */
  getWatchOptions() {
    return this.watchOptions;
  }
  setTypeAcquisition(newTypeAcquisition) {
    if (newTypeAcquisition) {
      this.typeAcquisition = this.removeLocalTypingsFromTypeAcquisition(newTypeAcquisition);
    }
  }
  getTypeAcquisition() {
    return this.typeAcquisition || {};
  }
  /** @internal */
  getChangesSinceVersion(lastKnownVersion, includeProjectReferenceRedirectInfo) {
    var _a, _b;
    const includeProjectReferenceRedirectInfoIfRequested = includeProjectReferenceRedirectInfo ? (files) => arrayFrom(files.entries(), ([fileName, isSourceOfProjectReferenceRedirect]) => ({
      fileName,
      isSourceOfProjectReferenceRedirect
    })) : (files) => arrayFrom(files.keys());
    if (!this.isInitialLoadPending()) {
      updateProjectIfDirty(this);
    }
    const info = {
      projectName: this.getProjectName(),
      version: this.projectProgramVersion,
      isInferred: isInferredProject(this),
      options: this.getCompilationSettings(),
      languageServiceDisabled: !this.languageServiceEnabled,
      lastFileExceededProgramSize: this.lastFileExceededProgramSize
    };
    const updatedFileNames = this.updatedFileNames;
    this.updatedFileNames = void 0;
    if (this.lastReportedFileNames && lastKnownVersion === this.lastReportedVersion) {
      if (this.projectProgramVersion === this.lastReportedVersion && !updatedFileNames) {
        return { info, projectErrors: this.getGlobalProjectErrors() };
      }
      const lastReportedFileNames = this.lastReportedFileNames;
      const externalFiles = ((_a = this.externalFiles) == null ? void 0 : _a.map((f) => ({
        fileName: toNormalizedPath(f),
        isSourceOfProjectReferenceRedirect: false
      }))) || emptyArray2;
      const currentFiles = arrayToMap(
        this.getFileNamesWithRedirectInfo(!!includeProjectReferenceRedirectInfo).concat(externalFiles),
        (info2) => info2.fileName,
        (info2) => info2.isSourceOfProjectReferenceRedirect
      );
      const added = /* @__PURE__ */ new Map();
      const removed = /* @__PURE__ */ new Map();
      const updated = updatedFileNames ? arrayFrom(updatedFileNames.keys()) : [];
      const updatedRedirects = [];
      forEachEntry(currentFiles, (isSourceOfProjectReferenceRedirect, fileName) => {
        if (!lastReportedFileNames.has(fileName)) {
          added.set(fileName, isSourceOfProjectReferenceRedirect);
        } else if (includeProjectReferenceRedirectInfo && isSourceOfProjectReferenceRedirect !== lastReportedFileNames.get(fileName)) {
          updatedRedirects.push({
            fileName,
            isSourceOfProjectReferenceRedirect
          });
        }
      });
      forEachEntry(lastReportedFileNames, (isSourceOfProjectReferenceRedirect, fileName) => {
        if (!currentFiles.has(fileName)) {
          removed.set(fileName, isSourceOfProjectReferenceRedirect);
        }
      });
      this.lastReportedFileNames = currentFiles;
      this.lastReportedVersion = this.projectProgramVersion;
      return {
        info,
        changes: {
          added: includeProjectReferenceRedirectInfoIfRequested(added),
          removed: includeProjectReferenceRedirectInfoIfRequested(removed),
          updated: includeProjectReferenceRedirectInfo ? updated.map((fileName) => ({
            fileName,
            isSourceOfProjectReferenceRedirect: this.isSourceOfProjectReferenceRedirect(fileName)
          })) : updated,
          updatedRedirects: includeProjectReferenceRedirectInfo ? updatedRedirects : void 0
        },
        projectErrors: this.getGlobalProjectErrors()
      };
    } else {
      const projectFileNames = this.getFileNamesWithRedirectInfo(!!includeProjectReferenceRedirectInfo);
      const externalFiles = ((_b = this.externalFiles) == null ? void 0 : _b.map((f) => ({
        fileName: toNormalizedPath(f),
        isSourceOfProjectReferenceRedirect: false
      }))) || emptyArray2;
      const allFiles = projectFileNames.concat(externalFiles);
      this.lastReportedFileNames = arrayToMap(
        allFiles,
        (info2) => info2.fileName,
        (info2) => info2.isSourceOfProjectReferenceRedirect
      );
      this.lastReportedVersion = this.projectProgramVersion;
      return {
        info,
        files: includeProjectReferenceRedirectInfo ? allFiles : allFiles.map((f) => f.fileName),
        projectErrors: this.getGlobalProjectErrors()
      };
    }
  }
  // remove a root file from project
  removeRoot(info) {
    this.rootFilesMap.delete(info.path);
  }
  /** @internal */
  isSourceOfProjectReferenceRedirect(fileName) {
    return !!this.program && this.program.isSourceOfProjectReferenceRedirect(fileName);
  }
  /** @internal */
  getGlobalPluginSearchPaths() {
    return [
      ...this.projectService.pluginProbeLocations,
      // ../../.. to walk from X/node_modules/typescript/lib/tsserver.js to X/node_modules/
      combinePaths(this.projectService.getExecutingFilePath(), "../../..")
    ];
  }
  enableGlobalPlugins(options) {
    if (!this.projectService.globalPlugins.length) return;
    const host = this.projectService.host;
    if (!host.require && !host.importPlugin) {
      this.projectService.logger.info("Plugins were requested but not running in environment that supports 'require'. Nothing will be loaded");
      return;
    }
    const searchPaths = this.getGlobalPluginSearchPaths();
    for (const globalPluginName of this.projectService.globalPlugins) {
      if (!globalPluginName) continue;
      if (options.plugins && options.plugins.some((p) => p.name === globalPluginName)) continue;
      this.projectService.logger.info(`Loading global plugin ${globalPluginName}`);
      this.enablePlugin({ name: globalPluginName, global: true }, searchPaths);
    }
  }
  enablePlugin(pluginConfigEntry, searchPaths) {
    this.projectService.requestEnablePlugin(this, pluginConfigEntry, searchPaths);
  }
  /** @internal */
  enableProxy(pluginModuleFactory, configEntry) {
    try {
      if (typeof pluginModuleFactory !== "function") {
        this.projectService.logger.info(`Skipped loading plugin ${configEntry.name} because it did not expose a proper factory function`);
        return;
      }
      const info = {
        config: configEntry,
        project: this,
        languageService: this.languageService,
        languageServiceHost: this,
        serverHost: this.projectService.host,
        session: this.projectService.session
      };
      const pluginModule = pluginModuleFactory({ typescript: ts_exports2 });
      const newLS = pluginModule.create(info);
      for (const k of Object.keys(this.languageService)) {
        if (!(k in newLS)) {
          this.projectService.logger.info(`Plugin activation warning: Missing proxied method ${k} in created LS. Patching.`);
          newLS[k] = this.languageService[k];
        }
      }
      this.projectService.logger.info(`Plugin validation succeeded`);
      this.languageService = newLS;
      this.plugins.push({ name: configEntry.name, module: pluginModule });
    } catch (e) {
      this.projectService.logger.info(`Plugin activation failed: ${e}`);
    }
  }
  /** @internal */
  onPluginConfigurationChanged(pluginName, configuration) {
    this.plugins.filter((plugin) => plugin.name === pluginName).forEach((plugin) => {
      if (plugin.module.onConfigurationChanged) {
        plugin.module.onConfigurationChanged(configuration);
      }
    });
  }
  /** Starts a new check for diagnostics. Call this if some file has updated that would cause diagnostics to be changed. */
  refreshDiagnostics() {
    this.projectService.sendProjectsUpdatedInBackgroundEvent();
  }
  /** @internal */
  getPackageJsonsVisibleToFile(fileName, rootDir) {
    if (this.projectService.serverMode !== 0 /* Semantic */) return emptyArray2;
    return this.projectService.getPackageJsonsVisibleToFile(fileName, this, rootDir);
  }
  /** @internal */
  getNearestAncestorDirectoryWithPackageJson(fileName) {
    return this.projectService.getNearestAncestorDirectoryWithPackageJson(fileName);
  }
  /** @internal */
  getPackageJsonsForAutoImport(rootDir) {
    return this.getPackageJsonsVisibleToFile(combinePaths(this.currentDirectory, inferredTypesContainingFile), rootDir);
  }
  /** @internal */
  getPackageJsonCache() {
    return this.projectService.packageJsonCache;
  }
  /** @internal */
  getCachedExportInfoMap() {
    return this.exportMapCache || (this.exportMapCache = createCacheableExportInfoMap(this));
  }
  /** @internal */
  clearCachedExportInfoMap() {
    var _a;
    (_a = this.exportMapCache) == null ? void 0 : _a.clear();
  }
  /** @internal */
  getModuleSpecifierCache() {
    return this.moduleSpecifierCache;
  }
  /** @internal */
  includePackageJsonAutoImports() {
    if (this.projectService.includePackageJsonAutoImports() === 0 /* Off */ || !this.languageServiceEnabled || isInsideNodeModules(this.currentDirectory) || !this.isDefaultProjectForOpenFiles()) {
      return 0 /* Off */;
    }
    return this.projectService.includePackageJsonAutoImports();
  }
  /** @internal */
  getHostForAutoImportProvider() {
    var _a, _b;
    if (this.program) {
      return {
        fileExists: this.program.fileExists,
        directoryExists: this.program.directoryExists,
        realpath: this.program.realpath || ((_a = this.projectService.host.realpath) == null ? void 0 : _a.bind(this.projectService.host)),
        getCurrentDirectory: this.getCurrentDirectory.bind(this),
        readFile: this.projectService.host.readFile.bind(this.projectService.host),
        getDirectories: this.projectService.host.getDirectories.bind(this.projectService.host),
        trace: (_b = this.projectService.host.trace) == null ? void 0 : _b.bind(this.projectService.host),
        useCaseSensitiveFileNames: this.program.useCaseSensitiveFileNames(),
        readDirectory: this.projectService.host.readDirectory.bind(this.projectService.host)
      };
    }
    return this.projectService.host;
  }
  /** @internal */
  getPackageJsonAutoImportProvider() {
    var _a, _b, _c;
    if (this.autoImportProviderHost === false) {
      return void 0;
    }
    if (this.projectService.serverMode !== 0 /* Semantic */) {
      this.autoImportProviderHost = false;
      return void 0;
    }
    if (this.autoImportProviderHost) {
      updateProjectIfDirty(this.autoImportProviderHost);
      if (this.autoImportProviderHost.isEmpty()) {
        this.autoImportProviderHost.close();
        this.autoImportProviderHost = void 0;
        return void 0;
      }
      return this.autoImportProviderHost.getCurrentProgram();
    }
    const dependencySelection = this.includePackageJsonAutoImports();
    if (dependencySelection) {
      (_a = tracing) == null ? void 0 : _a.push(tracing.Phase.Session, "getPackageJsonAutoImportProvider");
      const start = timestamp();
      this.autoImportProviderHost = AutoImportProviderProject.create(dependencySelection, this, this.getHostForAutoImportProvider(), this.documentRegistry);
      if (this.autoImportProviderHost) {
        updateProjectIfDirty(this.autoImportProviderHost);
        this.sendPerformanceEvent("CreatePackageJsonAutoImportProvider", timestamp() - start);
        (_b = tracing) == null ? void 0 : _b.pop();
        return this.autoImportProviderHost.getCurrentProgram();
      }
      (_c = tracing) == null ? void 0 : _c.pop();
    }
  }
  isDefaultProjectForOpenFiles() {
    return !!forEachEntry(
      this.projectService.openFiles,
      (_projectRootPath, path) => this.projectService.tryGetDefaultProjectForFile(this.projectService.getScriptInfoForPath(path)) === this
    );
  }
  /** @internal */
  watchNodeModulesForPackageJsonChanges(directoryPath) {
    return this.projectService.watchPackageJsonsInNodeModules(directoryPath, this);
  }
  /** @internal */
  getIncompleteCompletionsCache() {
    return this.projectService.getIncompleteCompletionsCache();
  }
  /** @internal */
  getNoDtsResolutionProject(rootFile) {
    Debug.assert(this.projectService.serverMode === 0 /* Semantic */);
    if (!this.noDtsResolutionProject) {
      this.noDtsResolutionProject = new AuxiliaryProject(this.projectService, this.documentRegistry, this.getCompilerOptionsForNoDtsResolutionProject(), this.currentDirectory);
    }
    if (this.noDtsResolutionProject.rootFile !== rootFile) {
      this.projectService.setFileNamesOfAutpImportProviderOrAuxillaryProject(this.noDtsResolutionProject, [rootFile]);
      this.noDtsResolutionProject.rootFile = rootFile;
    }
    return this.noDtsResolutionProject;
  }
  /** @internal */
  runWithTemporaryFileUpdate(rootFile, updatedText, cb) {
    var _a, _b, _c, _d;
    const originalProgram = this.program;
    const rootSourceFile = Debug.checkDefined((_a = this.program) == null ? void 0 : _a.getSourceFile(rootFile), "Expected file to be part of program");
    const originalText = Debug.checkDefined(rootSourceFile.getFullText());
    (_b = this.getScriptInfo(rootFile)) == null ? void 0 : _b.editContent(0, originalText.length, updatedText);
    this.updateGraph();
    try {
      cb(this.program, originalProgram, (_c = this.program) == null ? void 0 : _c.getSourceFile(rootFile));
    } finally {
      (_d = this.getScriptInfo(rootFile)) == null ? void 0 : _d.editContent(0, updatedText.length, originalText);
    }
  }
  getCompilerOptionsForNoDtsResolutionProject() {
    return {
      ...this.getCompilerOptions(),
      noDtsResolution: true,
      allowJs: true,
      maxNodeModuleJsDepth: 3,
      diagnostics: false,
      skipLibCheck: true,
      sourceMap: false,
      types: emptyArray,
      lib: emptyArray,
      noLib: true
    };
  }
};
function getUnresolvedImports(program, cachedUnresolvedImportsPerFile) {
  var _a, _b;
  const sourceFiles = program.getSourceFiles();
  (_a = tracing) == null ? void 0 : _a.push(tracing.Phase.Session, "getUnresolvedImports", { count: sourceFiles.length });
  const ambientModules = program.getTypeChecker().getAmbientModules().map((mod) => stripQuotes(mod.getName()));
  const result = sortAndDeduplicate(flatMap(sourceFiles, (sourceFile) => extractUnresolvedImportsFromSourceFile(
    program,
    sourceFile,
    ambientModules,
    cachedUnresolvedImportsPerFile
  )));
  (_b = tracing) == null ? void 0 : _b.pop();
  return result;
}
function extractUnresolvedImportsFromSourceFile(program, file, ambientModules, cachedUnresolvedImportsPerFile) {
  return getOrUpdate(cachedUnresolvedImportsPerFile, file.path, () => {
    let unresolvedImports;
    program.forEachResolvedModule(({ resolvedModule }, name) => {
      if ((!resolvedModule || !resolutionExtensionIsTSOrJson(resolvedModule.extension)) && !isExternalModuleNameRelative(name) && !ambientModules.some((m) => m === name)) {
        unresolvedImports = append(unresolvedImports, parsePackageName(name).packageName);
      }
    }, file);
    return unresolvedImports || emptyArray2;
  });
}
var InferredProject2 = class extends Project2 {
  /** @internal */
  constructor(projectService, documentRegistry, compilerOptions, watchOptions, projectRootPath, currentDirectory, typeAcquisition) {
    super(
      projectService.newInferredProjectName(),
      0 /* Inferred */,
      projectService,
      documentRegistry,
      // TODO: GH#18217
      /*files*/
      void 0,
      /*lastFileExceededProgramSize*/
      void 0,
      compilerOptions,
      /*compileOnSaveEnabled*/
      false,
      watchOptions,
      projectService.host,
      currentDirectory
    );
    this._isJsInferredProject = false;
    this.typeAcquisition = typeAcquisition;
    this.projectRootPath = projectRootPath && projectService.toCanonicalFileName(projectRootPath);
    if (!projectRootPath && !projectService.useSingleInferredProject) {
      this.canonicalCurrentDirectory = projectService.toCanonicalFileName(this.currentDirectory);
    }
    this.enableGlobalPlugins(this.getCompilerOptions());
  }
  toggleJsInferredProject(isJsInferredProject) {
    if (isJsInferredProject !== this._isJsInferredProject) {
      this._isJsInferredProject = isJsInferredProject;
      this.setCompilerOptions();
    }
  }
  setCompilerOptions(options) {
    if (!options && !this.getCompilationSettings()) {
      return;
    }
    const newOptions = cloneCompilerOptions(options || this.getCompilationSettings());
    if (this._isJsInferredProject && typeof newOptions.maxNodeModuleJsDepth !== "number") {
      newOptions.maxNodeModuleJsDepth = 2;
    } else if (!this._isJsInferredProject) {
      newOptions.maxNodeModuleJsDepth = void 0;
    }
    newOptions.allowJs = true;
    super.setCompilerOptions(newOptions);
  }
  addRoot(info) {
    Debug.assert(info.isScriptOpen());
    this.projectService.startWatchingConfigFilesForInferredProjectRoot(info);
    if (!this._isJsInferredProject && info.isJavaScript()) {
      this.toggleJsInferredProject(
        /*isJsInferredProject*/
        true
      );
    } else if (this.isOrphan() && this._isJsInferredProject && !info.isJavaScript()) {
      this.toggleJsInferredProject(
        /*isJsInferredProject*/
        false
      );
    }
    super.addRoot(info);
  }
  removeRoot(info) {
    this.projectService.stopWatchingConfigFilesForScriptInfo(info);
    super.removeRoot(info);
    if (!this.isOrphan() && this._isJsInferredProject && info.isJavaScript()) {
      if (every(this.getRootScriptInfos(), (rootInfo) => !rootInfo.isJavaScript())) {
        this.toggleJsInferredProject(
          /*isJsInferredProject*/
          false
        );
      }
    }
  }
  /** @internal */
  isOrphan() {
    return !this.hasRoots();
  }
  isProjectWithSingleRoot() {
    return !this.projectRootPath && !this.projectService.useSingleInferredProject || this.getRootScriptInfos().length === 1;
  }
  close() {
    forEach(this.getRootScriptInfos(), (info) => this.projectService.stopWatchingConfigFilesForScriptInfo(info));
    super.close();
  }
  getTypeAcquisition() {
    return this.typeAcquisition || {
      enable: allRootFilesAreJsOrDts(this),
      include: emptyArray,
      exclude: emptyArray
    };
  }
};
var AuxiliaryProject = class extends Project2 {
  constructor(projectService, documentRegistry, compilerOptions, currentDirectory) {
    super(
      projectService.newAuxiliaryProjectName(),
      4 /* Auxiliary */,
      projectService,
      documentRegistry,
      /*hasExplicitListOfFiles*/
      false,
      /*lastFileExceededProgramSize*/
      void 0,
      compilerOptions,
      /*compileOnSaveEnabled*/
      false,
      /*watchOptions*/
      void 0,
      projectService.host,
      currentDirectory
    );
  }
  isOrphan() {
    return true;
  }
  scheduleInvalidateResolutionsOfFailedLookupLocations() {
    return;
  }
};
var _AutoImportProviderProject = class _AutoImportProviderProject extends Project2 {
  /** @internal */
  constructor(hostProject, initialRootNames, documentRegistry, compilerOptions) {
    super(
      hostProject.projectService.newAutoImportProviderProjectName(),
      3 /* AutoImportProvider */,
      hostProject.projectService,
      documentRegistry,
      /*hasExplicitListOfFiles*/
      false,
      /*lastFileExceededProgramSize*/
      void 0,
      compilerOptions,
      /*compileOnSaveEnabled*/
      false,
      hostProject.getWatchOptions(),
      hostProject.projectService.host,
      hostProject.currentDirectory
    );
    this.hostProject = hostProject;
    this.rootFileNames = initialRootNames;
    this.useSourceOfProjectReferenceRedirect = maybeBind(this.hostProject, this.hostProject.useSourceOfProjectReferenceRedirect);
    this.getParsedCommandLine = maybeBind(this.hostProject, this.hostProject.getParsedCommandLine);
  }
  /** @internal */
  static getRootFileNames(dependencySelection, hostProject, host, compilerOptions) {
    var _a, _b;
    if (!dependencySelection) {
      return emptyArray;
    }
    const program = hostProject.getCurrentProgram();
    if (!program) {
      return emptyArray;
    }
    const start = timestamp();
    let dependencyNames;
    let rootNames;
    const rootFileName = combinePaths(hostProject.currentDirectory, inferredTypesContainingFile);
    const packageJsons = hostProject.getPackageJsonsForAutoImport(combinePaths(hostProject.currentDirectory, rootFileName));
    for (const packageJson of packageJsons) {
      (_a = packageJson.dependencies) == null ? void 0 : _a.forEach((_, dependenyName) => addDependency(dependenyName));
      (_b = packageJson.peerDependencies) == null ? void 0 : _b.forEach((_, dependencyName) => addDependency(dependencyName));
    }
    let dependenciesAdded = 0;
    if (dependencyNames) {
      const symlinkCache = hostProject.getSymlinkCache();
      for (const name of arrayFrom(dependencyNames.keys())) {
        if (dependencySelection === 2 /* Auto */ && dependenciesAdded > this.maxDependencies) {
          hostProject.log(`AutoImportProviderProject: attempted to add more than ${this.maxDependencies} dependencies. Aborting.`);
          return emptyArray;
        }
        const packageJson = resolvePackageNameToPackageJson(
          name,
          hostProject.currentDirectory,
          compilerOptions,
          host,
          program.getModuleResolutionCache()
        );
        if (packageJson) {
          const entrypoints = getRootNamesFromPackageJson(packageJson, program, symlinkCache);
          if (entrypoints) {
            dependenciesAdded += addRootNames(entrypoints);
            continue;
          }
        }
        const done = forEach([hostProject.currentDirectory, hostProject.getGlobalTypingsCacheLocation()], (directory) => {
          if (directory) {
            const typesPackageJson = resolvePackageNameToPackageJson(
              `@types/${name}`,
              directory,
              compilerOptions,
              host,
              program.getModuleResolutionCache()
            );
            if (typesPackageJson) {
              const entrypoints = getRootNamesFromPackageJson(typesPackageJson, program, symlinkCache);
              dependenciesAdded += addRootNames(entrypoints);
              return true;
            }
          }
        });
        if (done) continue;
        if (packageJson && compilerOptions.allowJs && compilerOptions.maxNodeModuleJsDepth) {
          const entrypoints = getRootNamesFromPackageJson(
            packageJson,
            program,
            symlinkCache,
            /*resolveJs*/
            true
          );
          dependenciesAdded += addRootNames(entrypoints);
        }
      }
    }
    const references = program.getResolvedProjectReferences();
    let referencesAddded = 0;
    if ((references == null ? void 0 : references.length) && hostProject.projectService.getHostPreferences().includeCompletionsForModuleExports) {
      references.forEach((ref) => {
        if (ref == null ? void 0 : ref.commandLine.options.outFile) {
          referencesAddded += addRootNames(filterEntrypoints([
            changeExtension(ref.commandLine.options.outFile, ".d.ts")
          ]));
        } else if (ref) {
          const getCommonSourceDirectory2 = memoize(
            () => getCommonSourceDirectoryOfConfig(
              ref.commandLine,
              !hostProject.useCaseSensitiveFileNames()
            )
          );
          referencesAddded += addRootNames(filterEntrypoints(mapDefined(
            ref.commandLine.fileNames,
            (fileName) => !isDeclarationFileName(fileName) && !fileExtensionIs(fileName, ".json" /* Json */) && !program.getSourceFile(fileName) ? getOutputDeclarationFileName(
              fileName,
              ref.commandLine,
              !hostProject.useCaseSensitiveFileNames(),
              getCommonSourceDirectory2
            ) : void 0
          )));
        }
      });
    }
    if (rootNames == null ? void 0 : rootNames.size) {
      hostProject.log(`AutoImportProviderProject: found ${rootNames.size} root files in ${dependenciesAdded} dependencies ${referencesAddded} referenced projects in ${timestamp() - start} ms`);
    }
    return rootNames ? arrayFrom(rootNames.values()) : emptyArray;
    function addRootNames(entrypoints) {
      if (!(entrypoints == null ? void 0 : entrypoints.length)) return 0;
      rootNames ?? (rootNames = /* @__PURE__ */ new Set());
      entrypoints.forEach((entry) => rootNames.add(entry));
      return 1;
    }
    function addDependency(dependency) {
      if (!startsWith(dependency, "@types/")) {
        (dependencyNames || (dependencyNames = /* @__PURE__ */ new Set())).add(dependency);
      }
    }
    function getRootNamesFromPackageJson(packageJson, program2, symlinkCache, resolveJs) {
      var _a2;
      const entrypoints = getEntrypointsFromPackageJsonInfo(
        packageJson,
        compilerOptions,
        host,
        program2.getModuleResolutionCache(),
        resolveJs
      );
      if (entrypoints) {
        const real = (_a2 = host.realpath) == null ? void 0 : _a2.call(host, packageJson.packageDirectory);
        const realPath2 = real ? hostProject.toPath(real) : void 0;
        const isSymlink = realPath2 && realPath2 !== hostProject.toPath(packageJson.packageDirectory);
        if (isSymlink) {
          symlinkCache.setSymlinkedDirectory(packageJson.packageDirectory, {
            real: ensureTrailingDirectorySeparator(real),
            realPath: ensureTrailingDirectorySeparator(realPath2)
          });
        }
        return filterEntrypoints(entrypoints, isSymlink ? (entrypoint) => entrypoint.replace(packageJson.packageDirectory, real) : void 0);
      }
    }
    function filterEntrypoints(entrypoints, symlinkName) {
      return mapDefined(entrypoints, (entrypoint) => {
        const resolvedFileName = symlinkName ? symlinkName(entrypoint) : entrypoint;
        if (!program.getSourceFile(resolvedFileName) && !(symlinkName && program.getSourceFile(entrypoint))) {
          return resolvedFileName;
        }
      });
    }
  }
  /** @internal */
  static create(dependencySelection, hostProject, host, documentRegistry) {
    if (dependencySelection === 0 /* Off */) {
      return void 0;
    }
    const compilerOptions = {
      ...hostProject.getCompilerOptions(),
      ...this.compilerOptionsOverrides
    };
    const rootNames = this.getRootFileNames(dependencySelection, hostProject, host, compilerOptions);
    if (!rootNames.length) {
      return void 0;
    }
    return new _AutoImportProviderProject(hostProject, rootNames, documentRegistry, compilerOptions);
  }
  /** @internal */
  isEmpty() {
    return !some(this.rootFileNames);
  }
  /** @internal */
  isOrphan() {
    return true;
  }
  updateGraph() {
    let rootFileNames = this.rootFileNames;
    if (!rootFileNames) {
      rootFileNames = _AutoImportProviderProject.getRootFileNames(
        this.hostProject.includePackageJsonAutoImports(),
        this.hostProject,
        this.hostProject.getHostForAutoImportProvider(),
        this.getCompilationSettings()
      );
    }
    this.projectService.setFileNamesOfAutpImportProviderOrAuxillaryProject(this, rootFileNames);
    this.rootFileNames = rootFileNames;
    const oldProgram = this.getCurrentProgram();
    const hasSameSetOfFiles = super.updateGraph();
    if (oldProgram && oldProgram !== this.getCurrentProgram()) {
      this.hostProject.clearCachedExportInfoMap();
    }
    return hasSameSetOfFiles;
  }
  /** @internal */
  scheduleInvalidateResolutionsOfFailedLookupLocations() {
    return;
  }
  hasRoots() {
    var _a;
    return !!((_a = this.rootFileNames) == null ? void 0 : _a.length);
  }
  /** @internal */
  markAsDirty() {
    this.rootFileNames = void 0;
    super.markAsDirty();
  }
  getScriptFileNames() {
    return this.rootFileNames || emptyArray;
  }
  getLanguageService() {
    throw new Error("AutoImportProviderProject language service should never be used. To get the program, use `project.getCurrentProgram()`.");
  }
  /** @internal */
  onAutoImportProviderSettingsChanged() {
    throw new Error("AutoImportProviderProject is an auto import provider; use `markAsDirty()` instead.");
  }
  /** @internal */
  onPackageJsonChange() {
    throw new Error("package.json changes should be notified on an AutoImportProvider's host project");
  }
  getHostForAutoImportProvider() {
    throw new Error("AutoImportProviderProject cannot provide its own host; use `hostProject.getModuleResolutionHostForAutomImportProvider()` instead.");
  }
  getProjectReferences() {
    return this.hostProject.getProjectReferences();
  }
  /** @internal */
  includePackageJsonAutoImports() {
    return 0 /* Off */;
  }
  /** @internal */
  getSymlinkCache() {
    return this.hostProject.getSymlinkCache();
  }
  /** @internal */
  getModuleResolutionCache() {
    var _a;
    return (_a = this.hostProject.getCurrentProgram()) == null ? void 0 : _a.getModuleResolutionCache();
  }
};
_AutoImportProviderProject.maxDependencies = 10;
/** @internal */
_AutoImportProviderProject.compilerOptionsOverrides = {
  diagnostics: false,
  skipLibCheck: true,
  sourceMap: false,
  types: emptyArray,
  lib: emptyArray,
  noLib: true
};
var AutoImportProviderProject = _AutoImportProviderProject;
var ConfiguredProject2 = class extends Project2 {
  /** @internal */
  constructor(configFileName, canonicalConfigFilePath, projectService, documentRegistry, cachedDirectoryStructureHost, pendingUpdateReason) {
    super(
      configFileName,
      1 /* Configured */,
      projectService,
      documentRegistry,
      /*hasExplicitListOfFiles*/
      false,
      /*lastFileExceededProgramSize*/
      void 0,
      /*compilerOptions*/
      {},
      /*compileOnSaveEnabled*/
      false,
      /*watchOptions*/
      void 0,
      cachedDirectoryStructureHost,
      getDirectoryPath(configFileName)
    );
    this.canonicalConfigFilePath = canonicalConfigFilePath;
    /** @internal */
    this.openFileWatchTriggered = /* @__PURE__ */ new Map();
    /** @internal */
    this.canConfigFileJsonReportNoInputFiles = false;
    /** @internal */
    this.isInitialLoadPending = returnTrue;
    /** @internal */
    this.sendLoadingProjectFinish = false;
    this.pendingUpdateLevel = 2 /* Full */;
    this.pendingUpdateReason = pendingUpdateReason;
  }
  /** @internal */
  setCompilerHost(host) {
    this.compilerHost = host;
  }
  /** @internal */
  getCompilerHost() {
    return this.compilerHost;
  }
  /** @internal */
  useSourceOfProjectReferenceRedirect() {
    return this.languageServiceEnabled;
  }
  /** @internal */
  getParsedCommandLine(fileName) {
    const configFileName = asNormalizedPath(normalizePath(fileName));
    const canonicalConfigFilePath = asNormalizedPath(this.projectService.toCanonicalFileName(configFileName));
    let configFileExistenceInfo = this.projectService.configFileExistenceInfoCache.get(canonicalConfigFilePath);
    if (!configFileExistenceInfo) {
      this.projectService.configFileExistenceInfoCache.set(canonicalConfigFilePath, configFileExistenceInfo = { exists: this.projectService.host.fileExists(configFileName) });
    }
    this.projectService.ensureParsedConfigUptoDate(configFileName, canonicalConfigFilePath, configFileExistenceInfo, this);
    if (this.languageServiceEnabled && this.projectService.serverMode === 0 /* Semantic */) {
      this.projectService.watchWildcards(configFileName, configFileExistenceInfo, this);
    }
    return configFileExistenceInfo.exists ? configFileExistenceInfo.config.parsedCommandLine : void 0;
  }
  /** @internal */
  onReleaseParsedCommandLine(fileName) {
    this.releaseParsedConfig(asNormalizedPath(this.projectService.toCanonicalFileName(asNormalizedPath(normalizePath(fileName)))));
  }
  releaseParsedConfig(canonicalConfigFilePath) {
    this.projectService.stopWatchingWildCards(canonicalConfigFilePath, this);
    this.projectService.releaseParsedConfig(canonicalConfigFilePath, this);
  }
  /**
   * If the project has reload from disk pending, it reloads (and then updates graph as part of that) instead of just updating the graph
   * @returns: true if set of files in the project stays the same and false - otherwise.
   */
  updateGraph() {
    if (this.deferredClose) return false;
    const isDirty = this.dirty;
    this.isInitialLoadPending = returnFalse;
    const updateLevel = this.pendingUpdateLevel;
    this.pendingUpdateLevel = 0 /* Update */;
    let result;
    switch (updateLevel) {
      case 1 /* RootNamesAndUpdate */:
        this.openFileWatchTriggered.clear();
        result = this.projectService.reloadFileNamesOfConfiguredProject(this);
        break;
      case 2 /* Full */:
        this.openFileWatchTriggered.clear();
        const reason = Debug.checkDefined(this.pendingUpdateReason);
        this.projectService.reloadConfiguredProject(this, reason);
        result = true;
        break;
      default:
        result = super.updateGraph();
    }
    this.compilerHost = void 0;
    this.projectService.sendProjectLoadingFinishEvent(this);
    this.projectService.sendProjectTelemetry(this);
    if (updateLevel === 2 /* Full */ || // Already sent event through reload
    result && // Not new program
    (!isDirty || !this.triggerFileForConfigFileDiag || this.getCurrentProgram().structureIsReused === 2 /* Completely */)) {
      this.triggerFileForConfigFileDiag = void 0;
    } else if (!this.triggerFileForConfigFileDiag) {
      this.projectService.sendConfigFileDiagEvent(
        this,
        /*triggerFile*/
        void 0,
        /*force*/
        false
      );
    }
    return result;
  }
  /** @internal */
  getCachedDirectoryStructureHost() {
    return this.directoryStructureHost;
  }
  getConfigFilePath() {
    return asNormalizedPath(this.getProjectName());
  }
  getProjectReferences() {
    return this.projectReferences;
  }
  updateReferences(refs) {
    if (typeof process.versions.pnp !== `undefined`) {
      const basePath = this.getCurrentDirectory();
      const getPnpPath = (path) => {
        try {
          const pnpApi = getPnpApi(`${path}/`);
          if (!pnpApi) {
            return path;
          }
          const targetLocator = pnpApi.findPackageLocator(`${path}/`);
          const { packageLocation } = pnpApi.getPackageInformation(targetLocator);
          const request = combinePaths(targetLocator.name, getRelativePathFromDirectory(
            packageLocation,
            path,
            /*ignoreCase*/
            false
          ));
          return pnpApi.resolveToUnqualified(request, `${basePath}/`);
        } catch {
          return path;
        }
      };
      refs = refs == null ? void 0 : refs.map((r) => ({ ...r, path: getPnpPath(r.path) }));
    }
    this.projectReferences = refs;
    this.potentialProjectReferences = void 0;
  }
  /** @internal */
  setPotentialProjectReference(canonicalConfigPath) {
    Debug.assert(this.isInitialLoadPending());
    (this.potentialProjectReferences || (this.potentialProjectReferences = /* @__PURE__ */ new Set())).add(canonicalConfigPath);
  }
  /** @internal */
  getResolvedProjectReferenceToRedirect(fileName) {
    const program = this.getCurrentProgram();
    return program && program.getResolvedProjectReferenceToRedirect(fileName);
  }
  /** @internal */
  forEachResolvedProjectReference(cb) {
    var _a;
    return (_a = this.getCurrentProgram()) == null ? void 0 : _a.forEachResolvedProjectReference(cb);
  }
  /** @internal */
  enablePluginsWithOptions(options) {
    var _a;
    this.plugins.length = 0;
    if (!((_a = options.plugins) == null ? void 0 : _a.length) && !this.projectService.globalPlugins.length) return;
    const host = this.projectService.host;
    if (!host.require && !host.importPlugin) {
      this.projectService.logger.info("Plugins were requested but not running in environment that supports 'require'. Nothing will be loaded");
      return;
    }
    const searchPaths = this.getGlobalPluginSearchPaths();
    if (this.projectService.allowLocalPluginLoads) {
      const local = getDirectoryPath(this.canonicalConfigFilePath);
      this.projectService.logger.info(`Local plugin loading enabled; adding ${local} to search paths`);
      searchPaths.unshift(local);
    }
    if (options.plugins) {
      for (const pluginConfigEntry of options.plugins) {
        this.enablePlugin(pluginConfigEntry, searchPaths);
      }
    }
    return this.enableGlobalPlugins(options);
  }
  /**
   * Get the errors that dont have any file name associated
   */
  getGlobalProjectErrors() {
    return filter(this.projectErrors, (diagnostic) => !diagnostic.file) || emptyArray2;
  }
  /**
   * Get all the project errors
   */
  getAllProjectErrors() {
    return this.projectErrors || emptyArray2;
  }
  setProjectErrors(projectErrors) {
    this.projectErrors = projectErrors;
  }
  close() {
    this.projectService.configFileExistenceInfoCache.forEach((_configFileExistenceInfo, canonicalConfigFilePath) => this.releaseParsedConfig(canonicalConfigFilePath));
    this.projectErrors = void 0;
    this.openFileWatchTriggered.clear();
    this.compilerHost = void 0;
    super.close();
  }
  /** @internal */
  markAsDirty() {
    if (this.deferredClose) return;
    super.markAsDirty();
  }
  /** @internal */
  isSolution() {
    return this.getRootFilesMap().size === 0 && !this.canConfigFileJsonReportNoInputFiles;
  }
  /** @internal */
  isOrphan() {
    return !!this.deferredClose;
  }
  getEffectiveTypeRoots() {
    return getEffectiveTypeRoots(this.getCompilationSettings(), this) || [];
  }
  /** @internal */
  updateErrorOnNoInputFiles(fileNames) {
    updateErrorForNoInputFiles(fileNames, this.getConfigFilePath(), this.getCompilerOptions().configFile.configFileSpecs, this.projectErrors, this.canConfigFileJsonReportNoInputFiles);
  }
};
var ExternalProject = class extends Project2 {
  /** @internal */
  constructor(externalProjectName, projectService, documentRegistry, compilerOptions, lastFileExceededProgramSize, compileOnSaveEnabled, projectFilePath, watchOptions) {
    super(
      externalProjectName,
      2 /* External */,
      projectService,
      documentRegistry,
      /*hasExplicitListOfFiles*/
      true,
      lastFileExceededProgramSize,
      compilerOptions,
      compileOnSaveEnabled,
      watchOptions,
      projectService.host,
      getDirectoryPath(projectFilePath || normalizeSlashes(externalProjectName))
    );
    this.externalProjectName = externalProjectName;
    this.compileOnSaveEnabled = compileOnSaveEnabled;
    this.excludedFiles = [];
    this.enableGlobalPlugins(this.getCompilerOptions());
  }
  updateGraph() {
    const result = super.updateGraph();
    this.projectService.sendProjectTelemetry(this);
    return result;
  }
  getExcludedFiles() {
    return this.excludedFiles;
  }
};
function isInferredProject(project) {
  return project.projectKind === 0 /* Inferred */;
}
function isConfiguredProject(project) {
  return project.projectKind === 1 /* Configured */;
}
function isExternalProject(project) {
  return project.projectKind === 2 /* External */;
}
function isBackgroundProject(project) {
  return project.projectKind === 3 /* AutoImportProvider */ || project.projectKind === 4 /* Auxiliary */;
}
function isProjectDeferredClose(project) {
  return isConfiguredProject(project) && !!project.deferredClose;
}

// src/server/editorServices.ts
var maxProgramSizeForNonTsFiles = 20 * 1024 * 1024;
var maxFileSize = 4 * 1024 * 1024;
var ProjectsUpdatedInBackgroundEvent = "projectsUpdatedInBackground";
var ProjectLoadingStartEvent = "projectLoadingStart";
var ProjectLoadingFinishEvent = "projectLoadingFinish";
var LargeFileReferencedEvent = "largeFileReferenced";
var ConfigFileDiagEvent = "configFileDiag";
var ProjectLanguageServiceStateEvent = "projectLanguageServiceState";
var ProjectInfoTelemetryEvent = "projectInfo";
var OpenFileInfoTelemetryEvent = "openFileInfo";
var CreateFileWatcherEvent = "createFileWatcher";
var CreateDirectoryWatcherEvent = "createDirectoryWatcher";
var CloseFileWatcherEvent = "closeFileWatcher";
var ensureProjectForOpenFileSchedule = "*ensureProjectForOpenFiles*";
function prepareConvertersForEnumLikeCompilerOptions(commandLineOptions) {
  const map2 = /* @__PURE__ */ new Map();
  for (const option of commandLineOptions) {
    if (typeof option.type === "object") {
      const optionMap = option.type;
      optionMap.forEach((value) => {
        Debug.assert(typeof value === "number");
      });
      map2.set(option.name, optionMap);
    }
  }
  return map2;
}
var compilerOptionConverters = prepareConvertersForEnumLikeCompilerOptions(optionDeclarations);
var watchOptionsConverters = prepareConvertersForEnumLikeCompilerOptions(optionsForWatch);
var indentStyle = new Map(Object.entries({
  none: 0 /* None */,
  block: 1 /* Block */,
  smart: 2 /* Smart */
}));
var defaultTypeSafeList = {
  "jquery": {
    // jquery files can have names like "jquery-1.10.2.min.js" (or "jquery.intellisense.js")
    match: /jquery(-[\d.]+)?(\.intellisense)?(\.min)?\.js$/i,
    types: ["jquery"]
  },
  "WinJS": {
    // e.g. c:/temp/UWApp1/lib/winjs-4.0.1/js/base.js
    match: /^(.*\/winjs-[.\d]+)\/js\/base\.js$/i,
    // If the winjs/base.js file is found..
    exclude: [["^", 1, "/.*"]],
    // ..then exclude all files under the winjs folder
    types: ["winjs"]
    // And fetch the @types package for WinJS
  },
  "Kendo": {
    // e.g. /Kendo3/wwwroot/lib/kendo/kendo.all.min.js
    match: /^(.*\/kendo(-ui)?)\/kendo\.all(\.min)?\.js$/i,
    exclude: [["^", 1, "/.*"]],
    types: ["kendo-ui"]
  },
  "Office Nuget": {
    // e.g. /scripts/Office/1/excel-15.debug.js
    match: /^(.*\/office\/1)\/excel-\d+\.debug\.js$/i,
    // Office NuGet package is installed under a "1/office" folder
    exclude: [["^", 1, "/.*"]],
    // Exclude that whole folder if the file indicated above is found in it
    types: ["office"]
    // @types package to fetch instead
  },
  "References": {
    match: /^(.*\/_references\.js)$/i,
    exclude: [["^", 1, "$"]]
  }
};
function convertFormatOptions(protocolOptions) {
  if (isString(protocolOptions.indentStyle)) {
    protocolOptions.indentStyle = indentStyle.get(protocolOptions.indentStyle.toLowerCase());
    Debug.assert(protocolOptions.indentStyle !== void 0);
  }
  return protocolOptions;
}
function convertCompilerOptions(protocolOptions) {
  compilerOptionConverters.forEach((mappedValues, id) => {
    const propertyValue = protocolOptions[id];
    if (isString(propertyValue)) {
      protocolOptions[id] = mappedValues.get(propertyValue.toLowerCase());
    }
  });
  return protocolOptions;
}
function convertWatchOptions(protocolOptions, currentDirectory) {
  let watchOptions;
  let errors;
  optionsForWatch.forEach((option) => {
    const propertyValue = protocolOptions[option.name];
    if (propertyValue === void 0) return;
    const mappedValues = watchOptionsConverters.get(option.name);
    (watchOptions || (watchOptions = {}))[option.name] = mappedValues ? isString(propertyValue) ? mappedValues.get(propertyValue.toLowerCase()) : propertyValue : convertJsonOption(option, propertyValue, currentDirectory || "", errors || (errors = []));
  });
  return watchOptions && { watchOptions, errors };
}
function convertTypeAcquisition(protocolOptions) {
  let result;
  typeAcquisitionDeclarations.forEach((option) => {
    const propertyValue = protocolOptions[option.name];
    if (propertyValue === void 0) return;
    (result || (result = {}))[option.name] = propertyValue;
  });
  return result;
}
function tryConvertScriptKindName(scriptKindName) {
  return isString(scriptKindName) ? convertScriptKindName(scriptKindName) : scriptKindName;
}
function convertScriptKindName(scriptKindName) {
  switch (scriptKindName) {
    case "JS":
      return 1 /* JS */;
    case "JSX":
      return 2 /* JSX */;
    case "TS":
      return 3 /* TS */;
    case "TSX":
      return 4 /* TSX */;
    default:
      return 0 /* Unknown */;
  }
}
function convertUserPreferences(preferences) {
  const { lazyConfiguredProjectsFromExternalProject: _, ...userPreferences } = preferences;
  return userPreferences;
}
var fileNamePropertyReader = {
  getFileName: (x) => x,
  getScriptKind: (fileName, extraFileExtensions) => {
    let result;
    if (extraFileExtensions) {
      const fileExtension = getAnyExtensionFromPath(fileName);
      if (fileExtension) {
        some(extraFileExtensions, (info) => {
          if (info.extension === fileExtension) {
            result = info.scriptKind;
            return true;
          }
          return false;
        });
      }
    }
    return result;
  },
  hasMixedContent: (fileName, extraFileExtensions) => some(extraFileExtensions, (ext) => ext.isMixedContent && fileExtensionIs(fileName, ext.extension))
};
var externalFilePropertyReader = {
  getFileName: (x) => x.fileName,
  getScriptKind: (x) => tryConvertScriptKindName(x.scriptKind),
  // TODO: GH#18217
  hasMixedContent: (x) => !!x.hasMixedContent
};
function findProjectByName(projectName, projects) {
  for (const proj of projects) {
    if (proj.getProjectName() === projectName) {
      return proj;
    }
  }
}
var nullTypingsInstaller = {
  isKnownTypesPackageName: returnFalse,
  // Should never be called because we never provide a types registry.
  installPackage: notImplemented,
  enqueueInstallTypingsRequest: noop,
  attach: noop,
  onProjectClosed: noop,
  globalTypingsCacheLocation: void 0
  // TODO: GH#18217
};
var noopConfigFileWatcher = { close: noop };
function getConfigFileNameFromCache(info, cache) {
  if (!cache || isAncestorConfigFileInfo(info)) return void 0;
  return cache.get(info.path);
}
function isOpenScriptInfo(infoOrFileNameOrConfig) {
  return !!infoOrFileNameOrConfig.containingProjects;
}
function isAncestorConfigFileInfo(infoOrFileNameOrConfig) {
  return !!infoOrFileNameOrConfig.configFileInfo;
}
var ConfiguredProjectLoadKind = /* @__PURE__ */ ((ConfiguredProjectLoadKind2) => {
  ConfiguredProjectLoadKind2[ConfiguredProjectLoadKind2["Find"] = 0] = "Find";
  ConfiguredProjectLoadKind2[ConfiguredProjectLoadKind2["Create"] = 1] = "Create";
  ConfiguredProjectLoadKind2[ConfiguredProjectLoadKind2["Reload"] = 2] = "Reload";
  return ConfiguredProjectLoadKind2;
})(ConfiguredProjectLoadKind || {});
function forEachAncestorProject(info, project, cb, kind, reason, allowDeferredClosed, reloadedProjects, delayReloadedConfiguredProjects) {
  while (true) {
    if (!project.isInitialLoadPending() && (!project.getCompilerOptions().composite || project.getCompilerOptions().disableSolutionSearching)) return;
    const configFileName = project.projectService.getConfigFileNameForFile({
      fileName: project.getConfigFilePath(),
      path: info.path,
      configFileInfo: true
    }, kind === 0 /* Find */);
    if (!configFileName) return;
    const ancestor = project.projectService.findCreateOrReloadConfiguredProject(
      configFileName,
      kind,
      reason,
      allowDeferredClosed,
      /*triggerFile*/
      void 0,
      reloadedProjects,
      /*delayLoad*/
      true,
      delayReloadedConfiguredProjects
    );
    if (!ancestor) return;
    if (ancestor.project.isInitialLoadPending() && project.getCompilerOptions().composite) {
      ancestor.project.setPotentialProjectReference(project.canonicalConfigFilePath);
    }
    const result = cb(ancestor.project);
    if (result) return result;
    project = ancestor.project;
  }
}
function forEachResolvedProjectReferenceProject(project, fileName, cb, kind, reason, allowDeferredClosed, triggerFile, reloadedProjects) {
  var _a;
  const resolvedRefs = (_a = project.getCurrentProgram()) == null ? void 0 : _a.getResolvedProjectReferences();
  if (!resolvedRefs) return void 0;
  const possibleDefaultRef = fileName ? project.getResolvedProjectReferenceToRedirect(fileName) : void 0;
  if (possibleDefaultRef) {
    const configFileName = toNormalizedPath(possibleDefaultRef.sourceFile.fileName);
    const child = project.projectService.findConfiguredProjectByProjectName(
      configFileName,
      allowDeferredClosed
    );
    if (child) {
      const result = callbackWithProjectFoundUsingFind(child);
      if (result) return result;
    } else if (kind !== 0 /* Find */) {
      const result = forEachResolvedProjectReferenceProjectWorker(
        resolvedRefs,
        project.getCompilerOptions(),
        (ref, loadKind) => possibleDefaultRef === ref ? callback(ref, loadKind) : void 0,
        kind,
        project.projectService
      );
      if (result) return result;
    }
  }
  return forEachResolvedProjectReferenceProjectWorker(
    resolvedRefs,
    project.getCompilerOptions(),
    (ref, loadKind) => possibleDefaultRef !== ref ? callback(ref, loadKind) : void 0,
    kind,
    project.projectService
  );
  function callback(ref, loadKind) {
    const result = project.projectService.findCreateOrReloadConfiguredProject(
      toNormalizedPath(ref.sourceFile.fileName),
      loadKind,
      reason,
      allowDeferredClosed,
      triggerFile,
      reloadedProjects
    );
    return result && (loadKind === kind ? cb(result.project, result.sentConfigFileDiag) : callbackWithProjectFoundUsingFind(result.project));
  }
  function callbackWithProjectFoundUsingFind(child) {
    let sentConfigFileDiag = false;
    switch (kind) {
      case 1 /* Create */:
        sentConfigFileDiag = updateConfiguredProject(child, triggerFile);
        break;
      case 2 /* Reload */:
        sentConfigFileDiag = child.projectService.reloadConfiguredProjectClearingSemanticCache(child, reason, reloadedProjects);
        break;
      case 0 /* Find */:
        break;
      default:
        Debug.assertNever(kind);
    }
    const result = cb(child, sentConfigFileDiag);
    if (result) return result;
  }
}
function forEachResolvedProjectReferenceProjectWorker(resolvedProjectReferences, parentOptions, cb, kind, projectService, seenResolvedRefs) {
  const loadKind = parentOptions.disableReferencedProjectLoad ? 0 /* Find */ : kind;
  return forEach(resolvedProjectReferences, (ref) => {
    if (!ref) return void 0;
    const configFileName = toNormalizedPath(ref.sourceFile.fileName);
    const canonicalPath = projectService.toCanonicalFileName(configFileName);
    const seenValue = seenResolvedRefs == null ? void 0 : seenResolvedRefs.get(canonicalPath);
    if (seenValue !== void 0 && seenValue >= loadKind) {
      return void 0;
    }
    const result = cb(ref, loadKind);
    if (result) {
      return result;
    }
    (seenResolvedRefs || (seenResolvedRefs = /* @__PURE__ */ new Map())).set(canonicalPath, loadKind);
    return ref.references && forEachResolvedProjectReferenceProjectWorker(ref.references, ref.commandLine.options, cb, loadKind, projectService, seenResolvedRefs);
  });
}
function forEachPotentialProjectReference(project, cb) {
  return project.potentialProjectReferences && forEachKey(project.potentialProjectReferences, cb);
}
function forEachAnyProjectReferenceKind(project, cb, cbProjectRef, cbPotentialProjectRef) {
  return project.getCurrentProgram() ? project.forEachResolvedProjectReference(cb) : project.isInitialLoadPending() ? forEachPotentialProjectReference(project, cbPotentialProjectRef) : forEach(project.getProjectReferences(), cbProjectRef);
}
function callbackRefProject(project, cb, refPath) {
  const refProject = refPath && project.projectService.configuredProjects.get(refPath);
  return refProject && cb(refProject);
}
function forEachReferencedProject(project, cb) {
  return forEachAnyProjectReferenceKind(
    project,
    (resolvedRef) => callbackRefProject(project, cb, resolvedRef.sourceFile.path),
    (projectRef) => callbackRefProject(project, cb, project.toPath(resolveProjectReferencePath(projectRef))),
    (potentialProjectRef) => callbackRefProject(project, cb, potentialProjectRef)
  );
}
function getDetailWatchInfo(watchType, project) {
  return `${isString(project) ? `Config: ${project} ` : project ? `Project: ${project.getProjectName()} ` : ""}WatchType: ${watchType}`;
}
function isScriptInfoWatchedFromNodeModules(info) {
  return !info.isScriptOpen() && info.mTime !== void 0;
}
function updateProjectIfDirty(project) {
  project.invalidateResolutionsOfFailedLookupLocations();
  return project.dirty && !project.updateGraph();
}
function updateWithTriggerFile(project, triggerFile, isReload) {
  if (!isReload) {
    project.invalidateResolutionsOfFailedLookupLocations();
    if (!project.dirty) return false;
  }
  project.triggerFileForConfigFileDiag = triggerFile;
  const updateLevel = project.pendingUpdateLevel;
  project.updateGraph();
  if (!project.triggerFileForConfigFileDiag && !isReload) return updateLevel === 2 /* Full */;
  const sent = project.projectService.sendConfigFileDiagEvent(project, triggerFile, isReload);
  project.triggerFileForConfigFileDiag = void 0;
  return sent;
}
function updateConfiguredProject(project, triggerFile) {
  if (triggerFile) {
    if (updateWithTriggerFile(
      project,
      triggerFile,
      /*isReload*/
      false
    )) return true;
  } else {
    updateProjectIfDirty(project);
  }
  return false;
}
function fileOpenReason(info) {
  return `Creating possible configured project for ${info.fileName} to open`;
}
function reloadReason(reason) {
  return `User requested reload projects: ${reason}`;
}
function setProjectOptionsUsed(project) {
  if (isConfiguredProject(project)) {
    project.projectOptions = true;
  }
}
function createProjectNameFactoryWithCounter(nameFactory) {
  let nextId = 1;
  return () => nameFactory(nextId++);
}
function getHostWatcherMap() {
  return { idToCallbacks: /* @__PURE__ */ new Map(), pathToId: /* @__PURE__ */ new Map() };
}
function getCanUseWatchEvents(service, canUseWatchEvents) {
  return !!canUseWatchEvents && !!service.eventHandler && !!service.session;
}
function createWatchFactoryHostUsingWatchEvents(service, canUseWatchEvents) {
  if (!getCanUseWatchEvents(service, canUseWatchEvents)) return void 0;
  const watchedFiles = getHostWatcherMap();
  const watchedDirectories = getHostWatcherMap();
  const watchedDirectoriesRecursive = getHostWatcherMap();
  let ids = 1;
  service.session.addProtocolHandler("watchChange" /* WatchChange */, (req) => {
    onWatchChange(req.arguments);
    return { responseRequired: false };
  });
  return {
    watchFile: watchFile2,
    watchDirectory,
    getCurrentDirectory: () => service.host.getCurrentDirectory(),
    useCaseSensitiveFileNames: service.host.useCaseSensitiveFileNames
  };
  function watchFile2(path, callback) {
    return getOrCreateFileWatcher(
      watchedFiles,
      path,
      callback,
      (id) => ({ eventName: CreateFileWatcherEvent, data: { id, path } })
    );
  }
  function watchDirectory(path, callback, recursive) {
    return getOrCreateFileWatcher(
      recursive ? watchedDirectoriesRecursive : watchedDirectories,
      path,
      callback,
      (id) => ({
        eventName: CreateDirectoryWatcherEvent,
        data: {
          id,
          path,
          recursive: !!recursive,
          // Special case node_modules as we watch it for changes to closed script infos as well
          ignoreUpdate: !path.endsWith("/node_modules") ? true : void 0
        }
      })
    );
  }
  function getOrCreateFileWatcher({ pathToId, idToCallbacks }, path, callback, event) {
    const key = service.toPath(path);
    let id = pathToId.get(key);
    if (!id) pathToId.set(key, id = ids++);
    let callbacks = idToCallbacks.get(id);
    if (!callbacks) {
      idToCallbacks.set(id, callbacks = /* @__PURE__ */ new Set());
      service.eventHandler(event(id));
    }
    callbacks.add(callback);
    return {
      close() {
        const callbacks2 = idToCallbacks.get(id);
        if (!(callbacks2 == null ? void 0 : callbacks2.delete(callback))) return;
        if (callbacks2.size) return;
        idToCallbacks.delete(id);
        pathToId.delete(key);
        service.eventHandler({ eventName: CloseFileWatcherEvent, data: { id } });
      }
    };
  }
  function onWatchChange(args) {
    if (isArray(args)) args.forEach(onWatchChangeRequestArgs);
    else onWatchChangeRequestArgs(args);
  }
  function onWatchChangeRequestArgs({ id, created, deleted, updated }) {
    onWatchEventType(id, created, 0 /* Created */);
    onWatchEventType(id, deleted, 2 /* Deleted */);
    onWatchEventType(id, updated, 1 /* Changed */);
  }
  function onWatchEventType(id, paths, eventKind) {
    if (!(paths == null ? void 0 : paths.length)) return;
    forEachCallback(watchedFiles, id, paths, (callback, eventPath) => callback(eventPath, eventKind));
    forEachCallback(watchedDirectories, id, paths, (callback, eventPath) => callback(eventPath));
    forEachCallback(watchedDirectoriesRecursive, id, paths, (callback, eventPath) => callback(eventPath));
  }
  function forEachCallback(hostWatcherMap, id, eventPaths, cb) {
    var _a;
    (_a = hostWatcherMap.idToCallbacks.get(id)) == null ? void 0 : _a.forEach((callback) => {
      eventPaths.forEach((eventPath) => cb(callback, normalizeSlashes(eventPath)));
    });
  }
}
var _ProjectService = class _ProjectService {
  constructor(opts) {
    /**
     * Container of all known scripts
     *
     * @internal
     */
    this.filenameToScriptInfo = /* @__PURE__ */ new Map();
    this.nodeModulesWatchers = /* @__PURE__ */ new Map();
    /**
     * Contains all the deleted script info's version information so that
     * it does not reset when creating script info again
     * (and could have potentially collided with version where contents mismatch)
     */
    this.filenameToScriptInfoVersion = /* @__PURE__ */ new Map();
    // Set of all '.js' files ever opened.
    this.allJsFilesForOpenFileTelemetry = /* @__PURE__ */ new Map();
    /**
     * maps external project file name to list of config files that were the part of this project
     */
    this.externalProjectToConfiguredProjectMap = /* @__PURE__ */ new Map();
    /**
     * external projects (configuration and list of root files is not controlled by tsserver)
     */
    this.externalProjects = [];
    /**
     * projects built from openFileRoots
     */
    this.inferredProjects = [];
    /**
     * projects specified by a tsconfig.json file
     */
    this.configuredProjects = /* @__PURE__ */ new Map();
    /** @internal */
    this.newInferredProjectName = createProjectNameFactoryWithCounter(makeInferredProjectName);
    /** @internal */
    this.newAutoImportProviderProjectName = createProjectNameFactoryWithCounter(makeAutoImportProviderProjectName);
    /** @internal */
    this.newAuxiliaryProjectName = createProjectNameFactoryWithCounter(makeAuxiliaryProjectName);
    /**
     * Open files: with value being project root path, and key being Path of the file that is open
     */
    this.openFiles = /* @__PURE__ */ new Map();
    /** Config files looked up and cached config files for open script info */
    this.configFileForOpenFiles = /* @__PURE__ */ new Map();
    /** Set of open script infos that are root of inferred project */
    this.rootOfInferredProjects = /* @__PURE__ */ new Set();
    /**
     * Map of open files that are opened without complete path but have projectRoot as current directory
     */
    this.openFilesWithNonRootedDiskPath = /* @__PURE__ */ new Map();
    this.compilerOptionsForInferredProjectsPerProjectRoot = /* @__PURE__ */ new Map();
    this.watchOptionsForInferredProjectsPerProjectRoot = /* @__PURE__ */ new Map();
    this.typeAcquisitionForInferredProjectsPerProjectRoot = /* @__PURE__ */ new Map();
    /**
     * Project size for configured or external projects
     */
    this.projectToSizeMap = /* @__PURE__ */ new Map();
    /**
     * This is a map of config file paths existence that doesnt need query to disk
     * - The entry can be present because there is inferred project that needs to watch addition of config file to directory
     *   In this case the exists could be true/false based on config file is present or not
     * - Or it is present if we have configured project open with config file at that location
     *   In this case the exists property is always true
     *
     * @internal
     */
    this.configFileExistenceInfoCache = /* @__PURE__ */ new Map();
    this.safelist = defaultTypeSafeList;
    this.legacySafelist = /* @__PURE__ */ new Map();
    this.pendingProjectUpdates = /* @__PURE__ */ new Map();
    /** @internal */
    this.pendingEnsureProjectForOpenFiles = false;
    /** Tracks projects that we have already sent telemetry for. */
    this.seenProjects = /* @__PURE__ */ new Map();
    this.sharedExtendedConfigFileWatchers = /* @__PURE__ */ new Map();
    this.extendedConfigCache = /* @__PURE__ */ new Map();
    /** @internal */
    this.baseline = noop;
    /** @internal */
    this.verifyDocumentRegistry = noop;
    /** @internal */
    this.verifyProgram = noop;
    /** @internal */
    this.onProjectCreation = noop;
    var _a;
    this.host = opts.host;
    this.logger = opts.logger;
    this.cancellationToken = opts.cancellationToken;
    this.useSingleInferredProject = opts.useSingleInferredProject;
    this.useInferredProjectPerProjectRoot = opts.useInferredProjectPerProjectRoot;
    this.typingsInstaller = opts.typingsInstaller || nullTypingsInstaller;
    this.throttleWaitMilliseconds = opts.throttleWaitMilliseconds;
    this.eventHandler = opts.eventHandler;
    this.suppressDiagnosticEvents = opts.suppressDiagnosticEvents;
    this.globalPlugins = opts.globalPlugins || emptyArray2;
    this.pluginProbeLocations = opts.pluginProbeLocations || emptyArray2;
    this.allowLocalPluginLoads = !!opts.allowLocalPluginLoads;
    this.typesMapLocation = opts.typesMapLocation === void 0 ? combinePaths(getDirectoryPath(this.getExecutingFilePath()), "typesMap.json") : opts.typesMapLocation;
    this.session = opts.session;
    this.jsDocParsingMode = opts.jsDocParsingMode;
    if (opts.serverMode !== void 0) {
      this.serverMode = opts.serverMode;
    } else {
      this.serverMode = 0 /* Semantic */;
    }
    if (this.host.realpath) {
      this.realpathToScriptInfos = createMultiMap();
    }
    this.currentDirectory = toNormalizedPath(this.host.getCurrentDirectory());
    this.toCanonicalFileName = createGetCanonicalFileName(this.host.useCaseSensitiveFileNames);
    this.globalCacheLocationDirectoryPath = this.typingsInstaller.globalTypingsCacheLocation ? ensureTrailingDirectorySeparator(this.toPath(this.typingsInstaller.globalTypingsCacheLocation)) : void 0;
    this.throttledOperations = new ThrottledOperations(this.host, this.logger);
    if (this.typesMapLocation) {
      this.loadTypesMap();
    } else {
      this.logger.info("No types map provided; using the default");
    }
    this.typingsInstaller.attach(this);
    this.hostConfiguration = {
      formatCodeOptions: getDefaultFormatCodeSettings(this.host.newLine),
      preferences: emptyOptions,
      hostInfo: "Unknown host",
      extraFileExtensions: []
    };
    this.documentRegistry = createDocumentRegistryInternal(this.host.useCaseSensitiveFileNames, this.currentDirectory, this.jsDocParsingMode, this);
    const watchLogLevel = this.logger.hasLevel(3 /* verbose */) ? 2 /* Verbose */ : this.logger.loggingEnabled() ? 1 /* TriggerOnly */ : 0 /* None */;
    const log = watchLogLevel !== 0 /* None */ ? (s) => this.logger.info(s) : noop;
    this.packageJsonCache = createPackageJsonCache(this);
    this.watchFactory = this.serverMode !== 0 /* Semantic */ ? {
      watchFile: returnNoopFileWatcher,
      watchDirectory: returnNoopFileWatcher
    } : getWatchFactory(
      createWatchFactoryHostUsingWatchEvents(this, opts.canUseWatchEvents) || this.host,
      watchLogLevel,
      log,
      getDetailWatchInfo
    );
    this.canUseWatchEvents = getCanUseWatchEvents(this, opts.canUseWatchEvents);
    this.pnpWatcher = this.watchPnpFile();
    (_a = opts.incrementalVerifier) == null ? void 0 : _a.call(opts, this);
  }
  toPath(fileName) {
    return toPath(fileName, this.currentDirectory, this.toCanonicalFileName);
  }
  /** @internal */
  getExecutingFilePath() {
    return this.getNormalizedAbsolutePath(this.host.getExecutingFilePath());
  }
  /** @internal */
  getNormalizedAbsolutePath(fileName) {
    return getNormalizedAbsolutePath(fileName, this.host.getCurrentDirectory());
  }
  /** @internal */
  setDocument(key, path, sourceFile) {
    const info = Debug.checkDefined(this.getScriptInfoForPath(path));
    info.cacheSourceFile = { key, sourceFile };
  }
  /** @internal */
  getDocument(key, path) {
    const info = this.getScriptInfoForPath(path);
    return info && info.cacheSourceFile && info.cacheSourceFile.key === key ? info.cacheSourceFile.sourceFile : void 0;
  }
  /** @internal */
  ensureInferredProjectsUpToDate_TestOnly() {
    this.ensureProjectStructuresUptoDate();
  }
  /** @internal */
  getCompilerOptionsForInferredProjects() {
    return this.compilerOptionsForInferredProjects;
  }
  /** @internal */
  onUpdateLanguageServiceStateForProject(project, languageServiceEnabled) {
    if (!this.eventHandler) {
      return;
    }
    const event = {
      eventName: ProjectLanguageServiceStateEvent,
      data: { project, languageServiceEnabled }
    };
    this.eventHandler(event);
  }
  loadTypesMap() {
    try {
      const fileContent = this.host.readFile(this.typesMapLocation);
      if (fileContent === void 0) {
        this.logger.info(`Provided types map file "${this.typesMapLocation}" doesn't exist`);
        return;
      }
      const raw = JSON.parse(fileContent);
      for (const k of Object.keys(raw.typesMap)) {
        raw.typesMap[k].match = new RegExp(raw.typesMap[k].match, "i");
      }
      this.safelist = raw.typesMap;
      for (const key in raw.simpleMap) {
        if (hasProperty(raw.simpleMap, key)) {
          this.legacySafelist.set(key, raw.simpleMap[key].toLowerCase());
        }
      }
    } catch (e) {
      this.logger.info(`Error loading types map: ${e}`);
      this.safelist = defaultTypeSafeList;
      this.legacySafelist.clear();
    }
  }
  // eslint-disable-line @typescript-eslint/unified-signatures
  updateTypingsForProject(response) {
    const project = this.findProject(response.projectName);
    if (!project) {
      return;
    }
    switch (response.kind) {
      case ActionSet:
        project.updateTypingFiles(
          response.compilerOptions,
          response.typeAcquisition,
          response.unresolvedImports,
          response.typings
        );
        return;
      case ActionInvalidate:
        project.enqueueInstallTypingsForProject(
          /*forceRefresh*/
          true
        );
        return;
    }
  }
  /** @internal */
  watchTypingLocations(response) {
    var _a;
    (_a = this.findProject(response.projectName)) == null ? void 0 : _a.watchTypingLocations(response.files);
  }
  /** @internal */
  delayEnsureProjectForOpenFiles() {
    if (!this.openFiles.size) return;
    this.pendingEnsureProjectForOpenFiles = true;
    this.throttledOperations.schedule(
      ensureProjectForOpenFileSchedule,
      /*delay*/
      2500,
      () => {
        if (this.pendingProjectUpdates.size !== 0) {
          this.delayEnsureProjectForOpenFiles();
        } else {
          if (this.pendingEnsureProjectForOpenFiles) {
            this.ensureProjectForOpenFiles();
            this.sendProjectsUpdatedInBackgroundEvent();
          }
        }
      }
    );
  }
  delayUpdateProjectGraph(project) {
    if (isProjectDeferredClose(project)) return;
    project.markAsDirty();
    if (isBackgroundProject(project)) return;
    const projectName = project.getProjectName();
    this.pendingProjectUpdates.set(projectName, project);
    this.throttledOperations.schedule(
      projectName,
      /*delay*/
      250,
      () => {
        if (this.pendingProjectUpdates.delete(projectName)) {
          updateProjectIfDirty(project);
        }
      }
    );
  }
  /** @internal */
  hasPendingProjectUpdate(project) {
    return this.pendingProjectUpdates.has(project.getProjectName());
  }
  /** @internal */
  sendProjectsUpdatedInBackgroundEvent() {
    if (!this.eventHandler) {
      return;
    }
    const event = {
      eventName: ProjectsUpdatedInBackgroundEvent,
      data: {
        openFiles: arrayFrom(this.openFiles.keys(), (path) => this.getScriptInfoForPath(path).fileName)
      }
    };
    this.eventHandler(event);
  }
  /** @internal */
  sendLargeFileReferencedEvent(file, fileSize) {
    if (!this.eventHandler) {
      return;
    }
    const event = {
      eventName: LargeFileReferencedEvent,
      data: { file, fileSize, maxFileSize }
    };
    this.eventHandler(event);
  }
  /** @internal */
  sendProjectLoadingStartEvent(project, reason) {
    if (!this.eventHandler) {
      return;
    }
    project.sendLoadingProjectFinish = true;
    const event = {
      eventName: ProjectLoadingStartEvent,
      data: { project, reason }
    };
    this.eventHandler(event);
  }
  /** @internal */
  sendProjectLoadingFinishEvent(project) {
    if (!this.eventHandler || !project.sendLoadingProjectFinish) {
      return;
    }
    project.sendLoadingProjectFinish = false;
    const event = {
      eventName: ProjectLoadingFinishEvent,
      data: { project }
    };
    this.eventHandler(event);
  }
  /** @internal */
  sendPerformanceEvent(kind, durationMs) {
    if (this.performanceEventHandler) {
      this.performanceEventHandler({ kind, durationMs });
    }
  }
  /** @internal */
  delayUpdateProjectGraphAndEnsureProjectStructureForOpenFiles(project) {
    this.delayUpdateProjectGraph(project);
    this.delayEnsureProjectForOpenFiles();
  }
  delayUpdateProjectGraphs(projects, clearSourceMapperCache) {
    if (projects.length) {
      for (const project of projects) {
        if (clearSourceMapperCache) project.clearSourceMapperCache();
        this.delayUpdateProjectGraph(project);
      }
      this.delayEnsureProjectForOpenFiles();
    }
  }
  setCompilerOptionsForInferredProjects(projectCompilerOptions, projectRootPath) {
    Debug.assert(projectRootPath === void 0 || this.useInferredProjectPerProjectRoot, "Setting compiler options per project root path is only supported when useInferredProjectPerProjectRoot is enabled");
    const compilerOptions = convertCompilerOptions(projectCompilerOptions);
    const watchOptions = convertWatchOptions(projectCompilerOptions, projectRootPath);
    const typeAcquisition = convertTypeAcquisition(projectCompilerOptions);
    compilerOptions.allowNonTsExtensions = true;
    const canonicalProjectRootPath = projectRootPath && this.toCanonicalFileName(projectRootPath);
    if (canonicalProjectRootPath) {
      this.compilerOptionsForInferredProjectsPerProjectRoot.set(canonicalProjectRootPath, compilerOptions);
      this.watchOptionsForInferredProjectsPerProjectRoot.set(canonicalProjectRootPath, watchOptions || false);
      this.typeAcquisitionForInferredProjectsPerProjectRoot.set(canonicalProjectRootPath, typeAcquisition);
    } else {
      this.compilerOptionsForInferredProjects = compilerOptions;
      this.watchOptionsForInferredProjects = watchOptions;
      this.typeAcquisitionForInferredProjects = typeAcquisition;
    }
    for (const project of this.inferredProjects) {
      if (canonicalProjectRootPath ? project.projectRootPath === canonicalProjectRootPath : !project.projectRootPath || !this.compilerOptionsForInferredProjectsPerProjectRoot.has(project.projectRootPath)) {
        project.setCompilerOptions(compilerOptions);
        project.setTypeAcquisition(typeAcquisition);
        project.setWatchOptions(watchOptions == null ? void 0 : watchOptions.watchOptions);
        project.setProjectErrors(watchOptions == null ? void 0 : watchOptions.errors);
        project.compileOnSaveEnabled = compilerOptions.compileOnSave;
        project.markAsDirty();
        this.delayUpdateProjectGraph(project);
      }
    }
    this.delayEnsureProjectForOpenFiles();
  }
  findProject(projectName) {
    if (projectName === void 0) {
      return void 0;
    }
    if (isInferredProjectName(projectName)) {
      return findProjectByName(projectName, this.inferredProjects);
    }
    return this.findExternalProjectByProjectName(projectName) || this.findConfiguredProjectByProjectName(toNormalizedPath(projectName));
  }
  /** @internal */
  forEachProject(cb) {
    this.externalProjects.forEach(cb);
    this.configuredProjects.forEach(cb);
    this.inferredProjects.forEach(cb);
  }
  /** @internal */
  forEachEnabledProject(cb) {
    this.forEachProject((project) => {
      if (!project.isOrphan() && project.languageServiceEnabled) {
        cb(project);
      }
    });
  }
  getDefaultProjectForFile(fileName, ensureProject) {
    return ensureProject ? this.ensureDefaultProjectForFile(fileName) : this.tryGetDefaultProjectForFile(fileName);
  }
  /** @internal */
  tryGetDefaultProjectForFile(fileNameOrScriptInfo) {
    const scriptInfo = isString(fileNameOrScriptInfo) ? this.getScriptInfoForNormalizedPath(fileNameOrScriptInfo) : fileNameOrScriptInfo;
    return scriptInfo && !scriptInfo.isOrphan() ? scriptInfo.getDefaultProject() : void 0;
  }
  /**
   * If there is default project calculation pending for this file,
   * then it completes that calculation so that correct default project is used for the project
   */
  tryGetDefaultProjectForEnsuringConfiguredProjectForFile(fileNameOrScriptInfo) {
    var _a;
    const scriptInfo = isString(fileNameOrScriptInfo) ? this.getScriptInfoForNormalizedPath(fileNameOrScriptInfo) : fileNameOrScriptInfo;
    if (!scriptInfo) return void 0;
    if ((_a = this.pendingOpenFileProjectUpdates) == null ? void 0 : _a.delete(scriptInfo.path)) {
      this.tryFindDefaultConfiguredProjectAndLoadAncestorsForOpenScriptInfo(
        scriptInfo,
        1 /* Create */
      );
      if (scriptInfo.isOrphan()) {
        this.assignOrphanScriptInfoToInferredProject(scriptInfo, this.openFiles.get(scriptInfo.path));
      }
    }
    return this.tryGetDefaultProjectForFile(scriptInfo);
  }
  /** @internal */
  ensureDefaultProjectForFile(fileNameOrScriptInfo) {
    return this.tryGetDefaultProjectForEnsuringConfiguredProjectForFile(fileNameOrScriptInfo) || this.doEnsureDefaultProjectForFile(fileNameOrScriptInfo);
  }
  doEnsureDefaultProjectForFile(fileNameOrScriptInfo) {
    this.ensureProjectStructuresUptoDate();
    const scriptInfo = isString(fileNameOrScriptInfo) ? this.getScriptInfoForNormalizedPath(fileNameOrScriptInfo) : fileNameOrScriptInfo;
    return scriptInfo ? scriptInfo.getDefaultProject() : (this.logErrorForScriptInfoNotFound(isString(fileNameOrScriptInfo) ? fileNameOrScriptInfo : fileNameOrScriptInfo.fileName), Errors.ThrowNoProject());
  }
  getScriptInfoEnsuringProjectsUptoDate(uncheckedFileName) {
    this.ensureProjectStructuresUptoDate();
    return this.getScriptInfo(uncheckedFileName);
  }
  /**
   * Ensures the project structures are upto date
   * This means,
   * - we go through all the projects and update them if they are dirty
   * - if updates reflect some change in structure or there was pending request to ensure projects for open files
   *   ensure that each open script info has project
   */
  ensureProjectStructuresUptoDate() {
    let hasChanges = this.pendingEnsureProjectForOpenFiles;
    this.pendingProjectUpdates.clear();
    const updateGraph = (project) => {
      hasChanges = updateProjectIfDirty(project) || hasChanges;
    };
    this.externalProjects.forEach(updateGraph);
    this.configuredProjects.forEach(updateGraph);
    this.inferredProjects.forEach(updateGraph);
    if (hasChanges) {
      this.ensureProjectForOpenFiles();
    }
  }
  getFormatCodeOptions(file) {
    const info = this.getScriptInfoForNormalizedPath(file);
    return info && info.getFormatCodeSettings() || this.hostConfiguration.formatCodeOptions;
  }
  getPreferences(file) {
    const info = this.getScriptInfoForNormalizedPath(file);
    return { ...this.hostConfiguration.preferences, ...info && info.getPreferences() };
  }
  getHostFormatCodeOptions() {
    return this.hostConfiguration.formatCodeOptions;
  }
  getHostPreferences() {
    return this.hostConfiguration.preferences;
  }
  onSourceFileChanged(info, eventKind) {
    Debug.assert(!info.isScriptOpen());
    if (eventKind === 2 /* Deleted */) {
      this.handleDeletedFile(
        info,
        /*deferredDelete*/
        true
      );
    } else {
      if (info.deferredDelete) info.deferredDelete = void 0;
      info.delayReloadNonMixedContentFile();
      this.delayUpdateProjectGraphs(
        info.containingProjects,
        /*clearSourceMapperCache*/
        false
      );
      this.handleSourceMapProjects(info);
    }
  }
  handleSourceMapProjects(info) {
    if (info.sourceMapFilePath) {
      if (isString(info.sourceMapFilePath)) {
        const sourceMapFileInfo = this.getScriptInfoForPath(info.sourceMapFilePath);
        this.delayUpdateSourceInfoProjects(sourceMapFileInfo == null ? void 0 : sourceMapFileInfo.sourceInfos);
      } else {
        this.delayUpdateSourceInfoProjects(info.sourceMapFilePath.sourceInfos);
      }
    }
    this.delayUpdateSourceInfoProjects(info.sourceInfos);
    if (info.declarationInfoPath) {
      this.delayUpdateProjectsOfScriptInfoPath(info.declarationInfoPath);
    }
  }
  delayUpdateSourceInfoProjects(sourceInfos) {
    if (sourceInfos) {
      sourceInfos.forEach((_value, path) => this.delayUpdateProjectsOfScriptInfoPath(path));
    }
  }
  delayUpdateProjectsOfScriptInfoPath(path) {
    const info = this.getScriptInfoForPath(path);
    if (info) {
      this.delayUpdateProjectGraphs(
        info.containingProjects,
        /*clearSourceMapperCache*/
        true
      );
    }
  }
  handleDeletedFile(info, deferredDelete) {
    Debug.assert(!info.isScriptOpen());
    this.delayUpdateProjectGraphs(
      info.containingProjects,
      /*clearSourceMapperCache*/
      false
    );
    this.handleSourceMapProjects(info);
    info.detachAllProjects();
    if (deferredDelete) {
      info.delayReloadNonMixedContentFile();
      info.deferredDelete = true;
    } else {
      this.deleteScriptInfo(info);
    }
  }
  /**
   * This is to watch whenever files are added or removed to the wildcard directories
   */
  watchWildcardDirectory(directory, flags, configFileName, config) {
    let watcher = this.watchFactory.watchDirectory(
      directory,
      (fileOrDirectory) => this.onWildCardDirectoryWatcherInvoke(
        directory,
        configFileName,
        config,
        result,
        fileOrDirectory
      ),
      flags,
      this.getWatchOptionsFromProjectWatchOptions(config.parsedCommandLine.watchOptions, getDirectoryPath(configFileName)),
      WatchType.WildcardDirectory,
      configFileName
    );
    const result = {
      packageJsonWatches: void 0,
      close() {
        var _a;
        if (watcher) {
          watcher.close();
          watcher = void 0;
          (_a = result.packageJsonWatches) == null ? void 0 : _a.forEach((watcher2) => {
            watcher2.projects.delete(result);
            watcher2.close();
          });
          result.packageJsonWatches = void 0;
        }
      }
    };
    return result;
  }
  onWildCardDirectoryWatcherInvoke(directory, configFileName, config, wildCardWatcher, fileOrDirectory) {
    const fileOrDirectoryPath = this.toPath(fileOrDirectory);
    const fsResult = config.cachedDirectoryStructureHost.addOrDeleteFileOrDirectory(fileOrDirectory, fileOrDirectoryPath);
    if (getBaseFileName(fileOrDirectoryPath) === "package.json" && !isInsideNodeModules(fileOrDirectoryPath) && (fsResult && fsResult.fileExists || !fsResult && this.host.fileExists(fileOrDirectory))) {
      const file = this.getNormalizedAbsolutePath(fileOrDirectory);
      this.logger.info(`Config: ${configFileName} Detected new package.json: ${file}`);
      this.packageJsonCache.addOrUpdate(file, fileOrDirectoryPath);
      this.watchPackageJsonFile(file, fileOrDirectoryPath, wildCardWatcher);
    }
    if (!(fsResult == null ? void 0 : fsResult.fileExists)) {
      this.sendSourceFileChange(fileOrDirectoryPath);
    }
    const configuredProjectForConfig = this.findConfiguredProjectByProjectName(configFileName);
    if (isIgnoredFileFromWildCardWatching({
      watchedDirPath: this.toPath(directory),
      fileOrDirectory,
      fileOrDirectoryPath,
      configFileName,
      extraFileExtensions: this.hostConfiguration.extraFileExtensions,
      currentDirectory: this.currentDirectory,
      options: config.parsedCommandLine.options,
      program: (configuredProjectForConfig == null ? void 0 : configuredProjectForConfig.getCurrentProgram()) || config.parsedCommandLine.fileNames,
      useCaseSensitiveFileNames: this.host.useCaseSensitiveFileNames,
      writeLog: (s) => this.logger.info(s),
      toPath: (s) => this.toPath(s),
      getScriptKind: configuredProjectForConfig ? (fileName) => configuredProjectForConfig.getScriptKind(fileName) : void 0
    })) return;
    if (config.updateLevel !== 2 /* Full */) config.updateLevel = 1 /* RootNamesAndUpdate */;
    config.projects.forEach((watchWildcardDirectories, projectCanonicalPath) => {
      var _a;
      if (!watchWildcardDirectories) return;
      const project = this.getConfiguredProjectByCanonicalConfigFilePath(projectCanonicalPath);
      if (!project) return;
      if (configuredProjectForConfig !== project && this.getHostPreferences().includeCompletionsForModuleExports) {
        const path = this.toPath(configFileName);
        if (find((_a = project.getCurrentProgram()) == null ? void 0 : _a.getResolvedProjectReferences(), (ref) => (ref == null ? void 0 : ref.sourceFile.path) === path)) {
          project.markAutoImportProviderAsDirty();
        }
      }
      const updateLevel = configuredProjectForConfig === project ? 1 /* RootNamesAndUpdate */ : 0 /* Update */;
      if (project.pendingUpdateLevel > updateLevel) return;
      if (this.openFiles.has(fileOrDirectoryPath)) {
        const info = Debug.checkDefined(this.getScriptInfoForPath(fileOrDirectoryPath));
        if (info.isAttached(project)) {
          const loadLevelToSet = Math.max(updateLevel, project.openFileWatchTriggered.get(fileOrDirectoryPath) || 0 /* Update */);
          project.openFileWatchTriggered.set(fileOrDirectoryPath, loadLevelToSet);
        } else {
          project.pendingUpdateLevel = updateLevel;
          this.delayUpdateProjectGraphAndEnsureProjectStructureForOpenFiles(project);
        }
      } else {
        project.pendingUpdateLevel = updateLevel;
        this.delayUpdateProjectGraphAndEnsureProjectStructureForOpenFiles(project);
      }
    });
  }
  delayUpdateProjectsFromParsedConfigOnConfigFileChange(canonicalConfigFilePath, loadReason) {
    const configFileExistenceInfo = this.configFileExistenceInfoCache.get(canonicalConfigFilePath);
    if (!(configFileExistenceInfo == null ? void 0 : configFileExistenceInfo.config)) return false;
    let scheduledAnyProjectUpdate = false;
    configFileExistenceInfo.config.updateLevel = 2 /* Full */;
    configFileExistenceInfo.config.projects.forEach((_watchWildcardDirectories, projectCanonicalPath) => {
      var _a;
      const project = this.getConfiguredProjectByCanonicalConfigFilePath(projectCanonicalPath);
      if (!project) return;
      scheduledAnyProjectUpdate = true;
      if (projectCanonicalPath === canonicalConfigFilePath) {
        if (project.isInitialLoadPending()) return;
        project.pendingUpdateLevel = 2 /* Full */;
        project.pendingUpdateReason = loadReason;
        this.delayUpdateProjectGraph(project);
        project.markAutoImportProviderAsDirty();
      } else {
        const path = this.toPath(canonicalConfigFilePath);
        project.resolutionCache.removeResolutionsFromProjectReferenceRedirects(path);
        this.delayUpdateProjectGraph(project);
        if (this.getHostPreferences().includeCompletionsForModuleExports && find((_a = project.getCurrentProgram()) == null ? void 0 : _a.getResolvedProjectReferences(), (ref) => (ref == null ? void 0 : ref.sourceFile.path) === path)) {
          project.markAutoImportProviderAsDirty();
        }
      }
    });
    return scheduledAnyProjectUpdate;
  }
  onConfigFileChanged(configFileName, canonicalConfigFilePath, eventKind) {
    const configFileExistenceInfo = this.configFileExistenceInfoCache.get(canonicalConfigFilePath);
    const project = this.getConfiguredProjectByCanonicalConfigFilePath(canonicalConfigFilePath);
    const wasDefferedClose = project == null ? void 0 : project.deferredClose;
    if (eventKind === 2 /* Deleted */) {
      configFileExistenceInfo.exists = false;
      if (project) project.deferredClose = true;
    } else {
      configFileExistenceInfo.exists = true;
      if (wasDefferedClose) {
        project.deferredClose = void 0;
        project.markAsDirty();
      }
    }
    this.delayUpdateProjectsFromParsedConfigOnConfigFileChange(
      canonicalConfigFilePath,
      "Change in config file detected"
    );
    const updatedProjects = new Set(project ? [project] : void 0);
    this.openFiles.forEach((_projectRootPath, path) => {
      var _a, _b;
      const configFileForOpenFile = this.configFileForOpenFiles.get(path);
      if (!((_a = configFileExistenceInfo.openFilesImpactedByConfigFile) == null ? void 0 : _a.has(path))) return;
      this.configFileForOpenFiles.delete(path);
      const info = this.getScriptInfoForPath(path);
      const newConfigFileNameForInfo = this.getConfigFileNameForFile(
        info,
        /*findFromCacheOnly*/
        false
      );
      if (!newConfigFileNameForInfo) return;
      const projectForInfo = this.findConfiguredProjectByProjectName(newConfigFileNameForInfo) ?? this.createConfiguredProject(
        newConfigFileNameForInfo,
        `Change in config file ${configFileName} detected, ${fileOpenReason(info)}`
      );
      if (!((_b = this.pendingOpenFileProjectUpdates) == null ? void 0 : _b.has(path))) {
        (this.pendingOpenFileProjectUpdates ?? (this.pendingOpenFileProjectUpdates = /* @__PURE__ */ new Map())).set(path, configFileForOpenFile);
      }
      if (tryAddToSet(updatedProjects, projectForInfo) && projectForInfo.isInitialLoadPending()) {
        this.delayUpdateProjectGraph(projectForInfo);
      }
    });
    this.delayEnsureProjectForOpenFiles();
  }
  removeProject(project) {
    this.logger.info("`remove Project::");
    project.print(
      /*writeProjectFileNames*/
      true,
      /*writeFileExplaination*/
      true,
      /*writeFileVersionAndText*/
      false
    );
    project.close();
    if (Debug.shouldAssert(1 /* Normal */)) {
      this.filenameToScriptInfo.forEach(
        (info) => Debug.assert(
          !info.isAttached(project),
          "Found script Info still attached to project",
          () => `${project.projectName}: ScriptInfos still attached: ${JSON.stringify(
            arrayFrom(
              mapDefinedIterator(
                this.filenameToScriptInfo.values(),
                (info2) => info2.isAttached(project) ? {
                  fileName: info2.fileName,
                  projects: info2.containingProjects.map((p) => p.projectName),
                  hasMixedContent: info2.hasMixedContent
                } : void 0
              )
            ),
            /*replacer*/
            void 0,
            " "
          )}`
        )
      );
    }
    this.pendingProjectUpdates.delete(project.getProjectName());
    switch (project.projectKind) {
      case 2 /* External */:
        unorderedRemoveItem(this.externalProjects, project);
        this.projectToSizeMap.delete(project.getProjectName());
        break;
      case 1 /* Configured */:
        this.configuredProjects.delete(project.canonicalConfigFilePath);
        this.projectToSizeMap.delete(project.canonicalConfigFilePath);
        break;
      case 0 /* Inferred */:
        unorderedRemoveItem(this.inferredProjects, project);
        break;
    }
  }
  /** @internal */
  assignOrphanScriptInfoToInferredProject(info, projectRootPath) {
    Debug.assert(info.isOrphan());
    const project = this.getOrCreateInferredProjectForProjectRootPathIfEnabled(info, projectRootPath) || this.getOrCreateSingleInferredProjectIfEnabled() || this.getOrCreateSingleInferredWithoutProjectRoot(
      info.isDynamic ? projectRootPath || this.currentDirectory : getDirectoryPath(
        isRootedDiskPath(info.fileName) ? info.fileName : getNormalizedAbsolutePath(
          info.fileName,
          projectRootPath ? this.getNormalizedAbsolutePath(projectRootPath) : this.currentDirectory
        )
      )
    );
    project.addRoot(info);
    if (info.containingProjects[0] !== project) {
      orderedRemoveItem(info.containingProjects, project);
      info.containingProjects.unshift(project);
    }
    project.updateGraph();
    if (!this.useSingleInferredProject && !project.projectRootPath) {
      for (const inferredProject of this.inferredProjects) {
        if (inferredProject === project || inferredProject.isOrphan()) {
          continue;
        }
        const roots = inferredProject.getRootScriptInfos();
        Debug.assert(roots.length === 1 || !!inferredProject.projectRootPath);
        if (roots.length === 1 && forEach(roots[0].containingProjects, (p) => p !== roots[0].containingProjects[0] && !p.isOrphan())) {
          inferredProject.removeFile(
            roots[0],
            /*fileExists*/
            true,
            /*detachFromProject*/
            true
          );
        }
      }
    }
    return project;
  }
  assignOrphanScriptInfosToInferredProject() {
    this.openFiles.forEach((projectRootPath, path) => {
      const info = this.getScriptInfoForPath(path);
      if (info.isOrphan()) {
        this.assignOrphanScriptInfoToInferredProject(info, projectRootPath);
      }
    });
  }
  /**
   * Remove this file from the set of open, non-configured files.
   * @param info The file that has been closed or newly configured
   */
  closeOpenFile(info, skipAssignOrphanScriptInfosToInferredProject) {
    var _a;
    const fileExists = info.isDynamic ? false : this.host.fileExists(info.fileName);
    info.close(fileExists);
    this.stopWatchingConfigFilesForScriptInfo(info);
    const canonicalFileName = this.toCanonicalFileName(info.fileName);
    if (this.openFilesWithNonRootedDiskPath.get(canonicalFileName) === info) {
      this.openFilesWithNonRootedDiskPath.delete(canonicalFileName);
    }
    let ensureProjectsForOpenFiles = false;
    for (const p of info.containingProjects) {
      if (isConfiguredProject(p)) {
        if (info.hasMixedContent) {
          info.registerFileUpdate();
        }
        const updateLevel = p.openFileWatchTriggered.get(info.path);
        if (updateLevel !== void 0) {
          p.openFileWatchTriggered.delete(info.path);
          if (p.pendingUpdateLevel < updateLevel) {
            p.pendingUpdateLevel = updateLevel;
            p.markFileAsDirty(info.path);
          }
        }
      } else if (isInferredProject(p) && p.isRoot(info)) {
        if (p.isProjectWithSingleRoot()) {
          ensureProjectsForOpenFiles = true;
        }
        p.removeFile(
          info,
          fileExists,
          /*detachFromProject*/
          true
        );
      }
      if (!p.languageServiceEnabled) {
        p.markAsDirty();
      }
    }
    this.openFiles.delete(info.path);
    this.configFileForOpenFiles.delete(info.path);
    (_a = this.pendingOpenFileProjectUpdates) == null ? void 0 : _a.delete(info.path);
    Debug.assert(!this.rootOfInferredProjects.has(info));
    if (!skipAssignOrphanScriptInfosToInferredProject && ensureProjectsForOpenFiles) {
      this.assignOrphanScriptInfosToInferredProject();
    }
    if (fileExists) {
      this.watchClosedScriptInfo(info);
    } else {
      this.handleDeletedFile(
        info,
        /*deferredDelete*/
        false
      );
    }
    return ensureProjectsForOpenFiles;
  }
  deleteScriptInfo(info) {
    Debug.assert(!info.isScriptOpen());
    this.filenameToScriptInfo.delete(info.path);
    this.filenameToScriptInfoVersion.set(info.path, info.textStorage.version);
    this.stopWatchingScriptInfo(info);
    const realpath = info.getRealpathIfDifferent();
    if (realpath) {
      this.realpathToScriptInfos.remove(realpath, info);
    }
    info.closeSourceMapFileWatcher();
  }
  configFileExists(configFileName, canonicalConfigFilePath, info) {
    const configFileExistenceInfo = this.configFileExistenceInfoCache.get(canonicalConfigFilePath);
    let openFilesImpactedByConfigFile;
    if (this.openFiles.has(info.path) && !isAncestorConfigFileInfo(info)) {
      if (configFileExistenceInfo) (configFileExistenceInfo.openFilesImpactedByConfigFile ?? (configFileExistenceInfo.openFilesImpactedByConfigFile = /* @__PURE__ */ new Set())).add(info.path);
      else (openFilesImpactedByConfigFile = /* @__PURE__ */ new Set()).add(info.path);
    }
    if (configFileExistenceInfo) return configFileExistenceInfo.exists;
    const exists = this.host.fileExists(configFileName);
    this.configFileExistenceInfoCache.set(canonicalConfigFilePath, { exists, openFilesImpactedByConfigFile });
    return exists;
  }
  createConfigFileWatcherForParsedConfig(configFileName, canonicalConfigFilePath, forProject) {
    var _a, _b;
    const configFileExistenceInfo = this.configFileExistenceInfoCache.get(canonicalConfigFilePath);
    if (!configFileExistenceInfo.watcher || configFileExistenceInfo.watcher === noopConfigFileWatcher) {
      configFileExistenceInfo.watcher = this.watchFactory.watchFile(
        configFileName,
        (_fileName, eventKind) => this.onConfigFileChanged(configFileName, canonicalConfigFilePath, eventKind),
        2e3 /* High */,
        this.getWatchOptionsFromProjectWatchOptions((_b = (_a = configFileExistenceInfo == null ? void 0 : configFileExistenceInfo.config) == null ? void 0 : _a.parsedCommandLine) == null ? void 0 : _b.watchOptions, getDirectoryPath(configFileName)),
        WatchType.ConfigFile,
        forProject
      );
    }
    const projects = configFileExistenceInfo.config.projects;
    projects.set(forProject.canonicalConfigFilePath, projects.get(forProject.canonicalConfigFilePath) || false);
  }
  /** @internal */
  releaseParsedConfig(canonicalConfigFilePath, forProject) {
    var _a, _b, _c;
    const configFileExistenceInfo = this.configFileExistenceInfoCache.get(canonicalConfigFilePath);
    if (!((_a = configFileExistenceInfo.config) == null ? void 0 : _a.projects.delete(forProject.canonicalConfigFilePath))) return;
    if ((_b = configFileExistenceInfo.config) == null ? void 0 : _b.projects.size) return;
    configFileExistenceInfo.config = void 0;
    clearSharedExtendedConfigFileWatcher(canonicalConfigFilePath, this.sharedExtendedConfigFileWatchers);
    Debug.checkDefined(configFileExistenceInfo.watcher);
    if ((_c = configFileExistenceInfo.openFilesImpactedByConfigFile) == null ? void 0 : _c.size) {
      if (configFileExistenceInfo.inferredProjectRoots) {
        if (!canWatchDirectoryOrFile(getPathComponents(getDirectoryPath(canonicalConfigFilePath)))) {
          configFileExistenceInfo.watcher.close();
          configFileExistenceInfo.watcher = noopConfigFileWatcher;
        }
      } else {
        configFileExistenceInfo.watcher.close();
        configFileExistenceInfo.watcher = void 0;
      }
    } else {
      configFileExistenceInfo.watcher.close();
      this.configFileExistenceInfoCache.delete(canonicalConfigFilePath);
    }
  }
  /**
   * This is called on file close or when its removed from inferred project as root,
   * so that we handle the watches and inferred project root data
   * @internal
   */
  stopWatchingConfigFilesForScriptInfo(info) {
    if (this.serverMode !== 0 /* Semantic */) return;
    const isRootOfInferredProject = this.rootOfInferredProjects.delete(info);
    const isOpen = info.isScriptOpen();
    if (isOpen && !isRootOfInferredProject) return;
    this.forEachConfigFileLocation(info, (canonicalConfigFilePath) => {
      var _a, _b, _c;
      const configFileExistenceInfo = this.configFileExistenceInfoCache.get(canonicalConfigFilePath);
      if (!configFileExistenceInfo) return;
      if (isOpen) {
        if (!((_a = configFileExistenceInfo == null ? void 0 : configFileExistenceInfo.openFilesImpactedByConfigFile) == null ? void 0 : _a.has(info.path))) return;
      } else {
        if (!((_b = configFileExistenceInfo.openFilesImpactedByConfigFile) == null ? void 0 : _b.delete(info.path))) return;
      }
      if (isRootOfInferredProject) {
        configFileExistenceInfo.inferredProjectRoots--;
        if (configFileExistenceInfo.watcher && !configFileExistenceInfo.config && !configFileExistenceInfo.inferredProjectRoots) {
          configFileExistenceInfo.watcher.close();
          configFileExistenceInfo.watcher = void 0;
        }
      }
      if (!((_c = configFileExistenceInfo.openFilesImpactedByConfigFile) == null ? void 0 : _c.size) && !configFileExistenceInfo.config) {
        Debug.assert(!configFileExistenceInfo.watcher);
        this.configFileExistenceInfoCache.delete(canonicalConfigFilePath);
      }
    });
  }
  /**
   * This is called by inferred project whenever script info is added as a root
   *
   * @internal
   */
  startWatchingConfigFilesForInferredProjectRoot(info) {
    if (this.serverMode !== 0 /* Semantic */) return;
    Debug.assert(info.isScriptOpen());
    this.rootOfInferredProjects.add(info);
    this.forEachConfigFileLocation(info, (canonicalConfigFilePath, configFileName) => {
      let configFileExistenceInfo = this.configFileExistenceInfoCache.get(canonicalConfigFilePath);
      if (!configFileExistenceInfo) {
        configFileExistenceInfo = { exists: this.host.fileExists(configFileName), inferredProjectRoots: 1 };
        this.configFileExistenceInfoCache.set(canonicalConfigFilePath, configFileExistenceInfo);
      } else {
        configFileExistenceInfo.inferredProjectRoots = (configFileExistenceInfo.inferredProjectRoots ?? 0) + 1;
      }
      (configFileExistenceInfo.openFilesImpactedByConfigFile ?? (configFileExistenceInfo.openFilesImpactedByConfigFile = /* @__PURE__ */ new Set())).add(info.path);
      configFileExistenceInfo.watcher || (configFileExistenceInfo.watcher = canWatchDirectoryOrFile(getPathComponents(getDirectoryPath(canonicalConfigFilePath))) ? this.watchFactory.watchFile(
        configFileName,
        (_filename, eventKind) => this.onConfigFileChanged(configFileName, canonicalConfigFilePath, eventKind),
        2e3 /* High */,
        this.hostConfiguration.watchOptions,
        WatchType.ConfigFileForInferredRoot
      ) : noopConfigFileWatcher);
    });
  }
  /**
   * This function tries to search for a tsconfig.json for the given file.
   * This is different from the method the compiler uses because
   * the compiler can assume it will always start searching in the
   * current directory (the directory in which tsc was invoked).
   * The server must start searching from the directory containing
   * the newly opened file.
   */
  forEachConfigFileLocation(info, action) {
    if (this.serverMode !== 0 /* Semantic */) {
      return void 0;
    }
    Debug.assert(!isOpenScriptInfo(info) || this.openFiles.has(info.path));
    const projectRootPath = this.openFiles.get(info.path);
    const scriptInfo = Debug.checkDefined(this.getScriptInfo(info.path));
    if (scriptInfo.isDynamic) return void 0;
    let searchPath = asNormalizedPath(getDirectoryPath(info.fileName));
    const isSearchPathInProjectRoot = () => containsPath(projectRootPath, searchPath, this.currentDirectory, !this.host.useCaseSensitiveFileNames);
    const anySearchPathOk = !projectRootPath || !isSearchPathInProjectRoot();
    let searchInDirectory = !isAncestorConfigFileInfo(info);
    do {
      if (searchInDirectory) {
        const canonicalSearchPath = normalizedPathToPath(searchPath, this.currentDirectory, this.toCanonicalFileName);
        const tsconfigFileName = asNormalizedPath(combinePaths(searchPath, "tsconfig.json"));
        let result = action(combinePaths(canonicalSearchPath, "tsconfig.json"), tsconfigFileName);
        if (result) return tsconfigFileName;
        const jsconfigFileName = asNormalizedPath(combinePaths(searchPath, "jsconfig.json"));
        result = action(combinePaths(canonicalSearchPath, "jsconfig.json"), jsconfigFileName);
        if (result) return jsconfigFileName;
        if (isNodeModulesDirectory(canonicalSearchPath)) {
          break;
        }
      }
      const parentPath = asNormalizedPath(getDirectoryPath(searchPath));
      if (parentPath === searchPath) break;
      searchPath = parentPath;
      searchInDirectory = true;
    } while (anySearchPathOk || isSearchPathInProjectRoot());
    return void 0;
  }
  /** @internal */
  findDefaultConfiguredProject(info) {
    var _a;
    return info.isScriptOpen() ? (_a = this.tryFindDefaultConfiguredProjectForOpenScriptInfo(
      info,
      0 /* Find */
    )) == null ? void 0 : _a.defaultProject : void 0;
  }
  /** Get cached configFileName for scriptInfo or ancestor of open script info */
  getConfigFileNameForFileFromCache(info, lookInPendingFilesForValue) {
    if (lookInPendingFilesForValue) {
      const result = getConfigFileNameFromCache(info, this.pendingOpenFileProjectUpdates);
      if (result !== void 0) return result;
    }
    return getConfigFileNameFromCache(info, this.configFileForOpenFiles);
  }
  /** Caches the configFilename for script info or ancestor of open script info */
  setConfigFileNameForFileInCache(info, configFileName) {
    if (!this.openFiles.has(info.path)) return;
    if (isAncestorConfigFileInfo(info)) return;
    this.configFileForOpenFiles.set(info.path, configFileName || false);
  }
  /**
   * This function tries to search for a tsconfig.json for the given file.
   * This is different from the method the compiler uses because
   * the compiler can assume it will always start searching in the
   * current directory (the directory in which tsc was invoked).
   * The server must start searching from the directory containing
   * the newly opened file.
   * If script info is passed in, it is asserted to be open script info
   * otherwise just file name
   * when findFromCacheOnly is true only looked up in cache instead of hitting disk to figure things out
   * @internal
   */
  getConfigFileNameForFile(info, findFromCacheOnly) {
    const fromCache = this.getConfigFileNameForFileFromCache(info, findFromCacheOnly);
    if (fromCache !== void 0) return fromCache || void 0;
    if (findFromCacheOnly) return void 0;
    const configFileName = this.forEachConfigFileLocation(info, (canonicalConfigFilePath, configFileName2) => this.configFileExists(configFileName2, canonicalConfigFilePath, info));
    this.logger.info(`getConfigFileNameForFile:: File: ${info.fileName} ProjectRootPath: ${this.openFiles.get(info.path)}:: Result: ${configFileName}`);
    this.setConfigFileNameForFileInCache(info, configFileName);
    return configFileName;
  }
  printProjects() {
    if (!this.logger.hasLevel(1 /* normal */)) {
      return;
    }
    this.logger.startGroup();
    this.externalProjects.forEach(printProjectWithoutFileNames);
    this.configuredProjects.forEach(printProjectWithoutFileNames);
    this.inferredProjects.forEach(printProjectWithoutFileNames);
    this.logger.info("Open files: ");
    this.openFiles.forEach((projectRootPath, path) => {
      const info = this.getScriptInfoForPath(path);
      this.logger.info(`	FileName: ${info.fileName} ProjectRootPath: ${projectRootPath}`);
      this.logger.info(`		Projects: ${info.containingProjects.map((p) => p.getProjectName())}`);
    });
    this.logger.endGroup();
  }
  /** @internal */
  findConfiguredProjectByProjectName(configFileName, allowDeferredClosed) {
    const canonicalConfigFilePath = asNormalizedPath(this.toCanonicalFileName(configFileName));
    const result = this.getConfiguredProjectByCanonicalConfigFilePath(canonicalConfigFilePath);
    return allowDeferredClosed ? result : !(result == null ? void 0 : result.deferredClose) ? result : void 0;
  }
  getConfiguredProjectByCanonicalConfigFilePath(canonicalConfigFilePath) {
    return this.configuredProjects.get(canonicalConfigFilePath);
  }
  findExternalProjectByProjectName(projectFileName) {
    return findProjectByName(projectFileName, this.externalProjects);
  }
  /** Get a filename if the language service exceeds the maximum allowed program size; otherwise returns undefined. */
  getFilenameForExceededTotalSizeLimitForNonTsFiles(name, options, fileNames, propertyReader) {
    if (options && options.disableSizeLimit || !this.host.getFileSize) {
      return;
    }
    let availableSpace = maxProgramSizeForNonTsFiles;
    this.projectToSizeMap.set(name, 0);
    this.projectToSizeMap.forEach((val) => availableSpace -= val || 0);
    let totalNonTsFileSize = 0;
    for (const f of fileNames) {
      const fileName = propertyReader.getFileName(f);
      if (hasTSFileExtension(fileName)) {
        continue;
      }
      totalNonTsFileSize += this.host.getFileSize(fileName);
      if (totalNonTsFileSize > maxProgramSizeForNonTsFiles || totalNonTsFileSize > availableSpace) {
        const top5LargestFiles = fileNames.map((f2) => propertyReader.getFileName(f2)).filter((name2) => !hasTSFileExtension(name2)).map((name2) => ({ name: name2, size: this.host.getFileSize(name2) })).sort((a, b) => b.size - a.size).slice(0, 5);
        this.logger.info(`Non TS file size exceeded limit (${totalNonTsFileSize}). Largest files: ${top5LargestFiles.map((file) => `${file.name}:${file.size}`).join(", ")}`);
        return fileName;
      }
    }
    this.projectToSizeMap.set(name, totalNonTsFileSize);
  }
  createExternalProject(projectFileName, files, options, typeAcquisition, excludedFiles) {
    const compilerOptions = convertCompilerOptions(options);
    const watchOptionsAndErrors = convertWatchOptions(options, getDirectoryPath(normalizeSlashes(projectFileName)));
    const project = new ExternalProject(
      projectFileName,
      this,
      this.documentRegistry,
      compilerOptions,
      /*lastFileExceededProgramSize*/
      this.getFilenameForExceededTotalSizeLimitForNonTsFiles(projectFileName, compilerOptions, files, externalFilePropertyReader),
      options.compileOnSave === void 0 ? true : options.compileOnSave,
      /*projectFilePath*/
      void 0,
      watchOptionsAndErrors == null ? void 0 : watchOptionsAndErrors.watchOptions
    );
    project.setProjectErrors(watchOptionsAndErrors == null ? void 0 : watchOptionsAndErrors.errors);
    project.excludedFiles = excludedFiles;
    this.addFilesToNonInferredProject(project, files, externalFilePropertyReader, typeAcquisition);
    this.externalProjects.push(project);
    return project;
  }
  /** @internal */
  sendProjectTelemetry(project) {
    if (this.seenProjects.has(project.projectName)) {
      setProjectOptionsUsed(project);
      return;
    }
    this.seenProjects.set(project.projectName, true);
    if (!this.eventHandler || !this.host.createSHA256Hash) {
      setProjectOptionsUsed(project);
      return;
    }
    const projectOptions = isConfiguredProject(project) ? project.projectOptions : void 0;
    setProjectOptionsUsed(project);
    const data = {
      projectId: this.host.createSHA256Hash(project.projectName),
      fileStats: countEachFileTypes(
        project.getScriptInfos(),
        /*includeSizes*/
        true
      ),
      compilerOptions: convertCompilerOptionsForTelemetry(project.getCompilationSettings()),
      typeAcquisition: convertTypeAcquisition2(project.getTypeAcquisition()),
      extends: projectOptions && projectOptions.configHasExtendsProperty,
      files: projectOptions && projectOptions.configHasFilesProperty,
      include: projectOptions && projectOptions.configHasIncludeProperty,
      exclude: projectOptions && projectOptions.configHasExcludeProperty,
      compileOnSave: project.compileOnSaveEnabled,
      configFileName: configFileName(),
      projectType: project instanceof ExternalProject ? "external" : "configured",
      languageServiceEnabled: project.languageServiceEnabled,
      version
    };
    this.eventHandler({ eventName: ProjectInfoTelemetryEvent, data });
    function configFileName() {
      if (!isConfiguredProject(project)) {
        return "other";
      }
      return getBaseConfigFileName(project.getConfigFilePath()) || "other";
    }
    function convertTypeAcquisition2({ enable: enable2, include, exclude }) {
      return {
        enable: enable2,
        include: include !== void 0 && include.length !== 0,
        exclude: exclude !== void 0 && exclude.length !== 0
      };
    }
  }
  addFilesToNonInferredProject(project, files, propertyReader, typeAcquisition) {
    this.updateNonInferredProjectFiles(project, files, propertyReader);
    project.setTypeAcquisition(typeAcquisition);
    project.markAsDirty();
  }
  /** @internal */
  createConfiguredProject(configFileName, reason) {
    var _a;
    (_a = tracing) == null ? void 0 : _a.instant(tracing.Phase.Session, "createConfiguredProject", { configFilePath: configFileName });
    this.logger.info(`Creating configuration project ${configFileName}`);
    const canonicalConfigFilePath = asNormalizedPath(this.toCanonicalFileName(configFileName));
    let configFileExistenceInfo = this.configFileExistenceInfoCache.get(canonicalConfigFilePath);
    if (!configFileExistenceInfo) {
      this.configFileExistenceInfoCache.set(canonicalConfigFilePath, configFileExistenceInfo = { exists: true });
    } else {
      configFileExistenceInfo.exists = true;
    }
    if (!configFileExistenceInfo.config) {
      configFileExistenceInfo.config = {
        cachedDirectoryStructureHost: createCachedDirectoryStructureHost(this.host, this.host.getCurrentDirectory(), this.host.useCaseSensitiveFileNames),
        projects: /* @__PURE__ */ new Map(),
        updateLevel: 2 /* Full */
      };
    }
    const project = new ConfiguredProject2(
      configFileName,
      canonicalConfigFilePath,
      this,
      this.documentRegistry,
      configFileExistenceInfo.config.cachedDirectoryStructureHost,
      reason
    );
    Debug.assert(!this.configuredProjects.has(canonicalConfigFilePath));
    this.configuredProjects.set(canonicalConfigFilePath, project);
    this.createConfigFileWatcherForParsedConfig(configFileName, canonicalConfigFilePath, project);
    return project;
  }
  /**
   * Read the config file of the project, and update the project root file names.
   */
  loadConfiguredProject(project, reason) {
    var _a, _b;
    (_a = tracing) == null ? void 0 : _a.push(tracing.Phase.Session, "loadConfiguredProject", { configFilePath: project.canonicalConfigFilePath });
    this.sendProjectLoadingStartEvent(project, reason);
    const configFilename = asNormalizedPath(normalizePath(project.getConfigFilePath()));
    const configFileExistenceInfo = this.ensureParsedConfigUptoDate(
      configFilename,
      project.canonicalConfigFilePath,
      this.configFileExistenceInfoCache.get(project.canonicalConfigFilePath),
      project
    );
    const parsedCommandLine = configFileExistenceInfo.config.parsedCommandLine;
    Debug.assert(!!parsedCommandLine.fileNames);
    const compilerOptions = parsedCommandLine.options;
    if (!project.projectOptions) {
      project.projectOptions = {
        configHasExtendsProperty: parsedCommandLine.raw.extends !== void 0,
        configHasFilesProperty: parsedCommandLine.raw.files !== void 0,
        configHasIncludeProperty: parsedCommandLine.raw.include !== void 0,
        configHasExcludeProperty: parsedCommandLine.raw.exclude !== void 0
      };
    }
    project.canConfigFileJsonReportNoInputFiles = canJsonReportNoInputFiles(parsedCommandLine.raw);
    project.setProjectErrors(parsedCommandLine.options.configFile.parseDiagnostics);
    project.updateReferences(parsedCommandLine.projectReferences);
    const lastFileExceededProgramSize = this.getFilenameForExceededTotalSizeLimitForNonTsFiles(project.canonicalConfigFilePath, compilerOptions, parsedCommandLine.fileNames, fileNamePropertyReader);
    if (lastFileExceededProgramSize) {
      project.disableLanguageService(lastFileExceededProgramSize);
      this.configFileExistenceInfoCache.forEach((_configFileExistenceInfo, canonicalConfigFilePath) => this.stopWatchingWildCards(canonicalConfigFilePath, project));
    } else {
      project.setCompilerOptions(compilerOptions);
      project.setWatchOptions(parsedCommandLine.watchOptions);
      project.enableLanguageService();
      this.watchWildcards(configFilename, configFileExistenceInfo, project);
    }
    project.enablePluginsWithOptions(compilerOptions);
    const filesToAdd = parsedCommandLine.fileNames.concat(project.getExternalFiles(2 /* Full */));
    this.updateRootAndOptionsOfNonInferredProject(project, filesToAdd, fileNamePropertyReader, compilerOptions, parsedCommandLine.typeAcquisition, parsedCommandLine.compileOnSave, parsedCommandLine.watchOptions);
    (_b = tracing) == null ? void 0 : _b.pop();
  }
  /** @internal */
  ensureParsedConfigUptoDate(configFilename, canonicalConfigFilePath, configFileExistenceInfo, forProject) {
    var _a, _b, _c;
    if (configFileExistenceInfo.config) {
      if (!configFileExistenceInfo.config.updateLevel) return configFileExistenceInfo;
      if (configFileExistenceInfo.config.updateLevel === 1 /* RootNamesAndUpdate */) {
        this.reloadFileNamesOfParsedConfig(configFilename, configFileExistenceInfo.config);
        return configFileExistenceInfo;
      }
    }
    const cachedDirectoryStructureHost = ((_a = configFileExistenceInfo.config) == null ? void 0 : _a.cachedDirectoryStructureHost) || createCachedDirectoryStructureHost(this.host, this.host.getCurrentDirectory(), this.host.useCaseSensitiveFileNames);
    const configFileContent = tryReadFile(configFilename, (fileName) => this.host.readFile(fileName));
    const configFile = parseJsonText(configFilename, isString(configFileContent) ? configFileContent : "");
    const configFileErrors = configFile.parseDiagnostics;
    if (!isString(configFileContent)) configFileErrors.push(configFileContent);
    const configDir = getDirectoryPath(configFilename);
    const parsedCommandLine = parseJsonSourceFileConfigFileContent(
      configFile,
      cachedDirectoryStructureHost,
      configDir,
      /*existingOptions*/
      void 0,
      configFilename,
      /*resolutionStack*/
      void 0,
      this.hostConfiguration.extraFileExtensions,
      this.extendedConfigCache
    );
    if (parsedCommandLine.errors.length) {
      configFileErrors.push(...parsedCommandLine.errors);
    }
    this.logger.info(`Config: ${configFilename} : ${JSON.stringify(
      {
        rootNames: parsedCommandLine.fileNames,
        options: parsedCommandLine.options,
        watchOptions: parsedCommandLine.watchOptions,
        projectReferences: parsedCommandLine.projectReferences
      },
      /*replacer*/
      void 0,
      " "
    )}`);
    const oldCommandLine = (_b = configFileExistenceInfo.config) == null ? void 0 : _b.parsedCommandLine;
    if (!configFileExistenceInfo.config) {
      configFileExistenceInfo.config = { parsedCommandLine, cachedDirectoryStructureHost, projects: /* @__PURE__ */ new Map() };
    } else {
      configFileExistenceInfo.config.parsedCommandLine = parsedCommandLine;
      configFileExistenceInfo.config.watchedDirectoriesStale = true;
      configFileExistenceInfo.config.updateLevel = void 0;
    }
    if (!oldCommandLine && !isJsonEqual(
      // Old options
      this.getWatchOptionsFromProjectWatchOptions(
        /*projectOptions*/
        void 0,
        configDir
      ),
      // New options
      this.getWatchOptionsFromProjectWatchOptions(parsedCommandLine.watchOptions, configDir)
    )) {
      (_c = configFileExistenceInfo.watcher) == null ? void 0 : _c.close();
      configFileExistenceInfo.watcher = void 0;
    }
    this.createConfigFileWatcherForParsedConfig(configFilename, canonicalConfigFilePath, forProject);
    updateSharedExtendedConfigFileWatcher(
      canonicalConfigFilePath,
      parsedCommandLine.options,
      this.sharedExtendedConfigFileWatchers,
      (extendedConfigFileName, extendedConfigFilePath) => this.watchFactory.watchFile(
        extendedConfigFileName,
        () => {
          var _a2;
          cleanExtendedConfigCache(this.extendedConfigCache, extendedConfigFilePath, (fileName) => this.toPath(fileName));
          let ensureProjectsForOpenFiles = false;
          (_a2 = this.sharedExtendedConfigFileWatchers.get(extendedConfigFilePath)) == null ? void 0 : _a2.projects.forEach((canonicalPath) => {
            ensureProjectsForOpenFiles = this.delayUpdateProjectsFromParsedConfigOnConfigFileChange(canonicalPath, `Change in extended config file ${extendedConfigFileName} detected`) || ensureProjectsForOpenFiles;
          });
          if (ensureProjectsForOpenFiles) this.delayEnsureProjectForOpenFiles();
        },
        2e3 /* High */,
        this.hostConfiguration.watchOptions,
        WatchType.ExtendedConfigFile,
        configFilename
      ),
      (fileName) => this.toPath(fileName)
    );
    return configFileExistenceInfo;
  }
  /** @internal */
  watchWildcards(configFileName, { exists, config }, forProject) {
    config.projects.set(forProject.canonicalConfigFilePath, true);
    if (exists) {
      if (config.watchedDirectories && !config.watchedDirectoriesStale) return;
      config.watchedDirectoriesStale = false;
      updateWatchingWildcardDirectories(
        config.watchedDirectories || (config.watchedDirectories = /* @__PURE__ */ new Map()),
        config.parsedCommandLine.wildcardDirectories,
        // Create new directory watcher
        (directory, flags) => this.watchWildcardDirectory(directory, flags, configFileName, config)
      );
    } else {
      config.watchedDirectoriesStale = false;
      if (!config.watchedDirectories) return;
      clearMap(config.watchedDirectories, closeFileWatcherOf);
      config.watchedDirectories = void 0;
    }
  }
  /** @internal */
  stopWatchingWildCards(canonicalConfigFilePath, forProject) {
    const configFileExistenceInfo = this.configFileExistenceInfoCache.get(canonicalConfigFilePath);
    if (!configFileExistenceInfo.config || !configFileExistenceInfo.config.projects.get(forProject.canonicalConfigFilePath)) {
      return;
    }
    configFileExistenceInfo.config.projects.set(forProject.canonicalConfigFilePath, false);
    if (forEachEntry(configFileExistenceInfo.config.projects, identity)) return;
    if (configFileExistenceInfo.config.watchedDirectories) {
      clearMap(configFileExistenceInfo.config.watchedDirectories, closeFileWatcherOf);
      configFileExistenceInfo.config.watchedDirectories = void 0;
    }
    configFileExistenceInfo.config.watchedDirectoriesStale = void 0;
  }
  updateNonInferredProjectFiles(project, files, propertyReader) {
    var _a;
    const projectRootFilesMap = project.getRootFilesMap();
    const newRootScriptInfoMap = /* @__PURE__ */ new Map();
    for (const f of files) {
      const newRootFile = propertyReader.getFileName(f);
      const fileName = toNormalizedPath(newRootFile);
      const isDynamic = isDynamicFileName(fileName);
      let path;
      if (!isDynamic && !project.fileExists(newRootFile)) {
        path = normalizedPathToPath(fileName, this.currentDirectory, this.toCanonicalFileName);
        const existingValue = projectRootFilesMap.get(path);
        if (existingValue) {
          if (((_a = existingValue.info) == null ? void 0 : _a.path) === path) {
            project.removeFile(
              existingValue.info,
              /*fileExists*/
              false,
              /*detachFromProject*/
              true
            );
            existingValue.info = void 0;
          }
          existingValue.fileName = fileName;
        } else {
          projectRootFilesMap.set(path, { fileName });
        }
      } else {
        const scriptKind = propertyReader.getScriptKind(f, this.hostConfiguration.extraFileExtensions);
        const hasMixedContent = propertyReader.hasMixedContent(f, this.hostConfiguration.extraFileExtensions);
        const scriptInfo = Debug.checkDefined(this.getOrCreateScriptInfoNotOpenedByClientForNormalizedPath(
          fileName,
          project.currentDirectory,
          scriptKind,
          hasMixedContent,
          project.directoryStructureHost,
          /*deferredDeleteOk*/
          false
        ));
        path = scriptInfo.path;
        const existingValue = projectRootFilesMap.get(path);
        if (!existingValue || existingValue.info !== scriptInfo) {
          project.addRoot(scriptInfo, fileName);
          if (scriptInfo.isScriptOpen()) {
            this.removeRootOfInferredProjectIfNowPartOfOtherProject(scriptInfo);
          }
        } else {
          existingValue.fileName = fileName;
        }
      }
      newRootScriptInfoMap.set(path, true);
    }
    if (projectRootFilesMap.size > newRootScriptInfoMap.size) {
      projectRootFilesMap.forEach((value, path) => {
        if (!newRootScriptInfoMap.has(path)) {
          if (value.info) {
            project.removeFile(
              value.info,
              project.fileExists(value.info.fileName),
              /*detachFromProject*/
              true
            );
          } else {
            projectRootFilesMap.delete(path);
          }
        }
      });
    }
  }
  updateRootAndOptionsOfNonInferredProject(project, newUncheckedFiles, propertyReader, newOptions, newTypeAcquisition, compileOnSave, watchOptions) {
    project.setCompilerOptions(newOptions);
    project.setWatchOptions(watchOptions);
    if (compileOnSave !== void 0) {
      project.compileOnSaveEnabled = compileOnSave;
    }
    this.addFilesToNonInferredProject(project, newUncheckedFiles, propertyReader, newTypeAcquisition);
  }
  /**
   * Reload the file names from config file specs and update the project graph
   *
   * @internal
   */
  reloadFileNamesOfConfiguredProject(project) {
    const fileNames = this.reloadFileNamesOfParsedConfig(project.getConfigFilePath(), this.configFileExistenceInfoCache.get(project.canonicalConfigFilePath).config);
    project.updateErrorOnNoInputFiles(fileNames);
    this.updateNonInferredProjectFiles(project, fileNames.concat(project.getExternalFiles(1 /* RootNamesAndUpdate */)), fileNamePropertyReader);
    project.markAsDirty();
    return project.updateGraph();
  }
  reloadFileNamesOfParsedConfig(configFileName, config) {
    if (config.updateLevel === void 0) return config.parsedCommandLine.fileNames;
    Debug.assert(config.updateLevel === 1 /* RootNamesAndUpdate */);
    const configFileSpecs = config.parsedCommandLine.options.configFile.configFileSpecs;
    const fileNames = getFileNamesFromConfigSpecs(
      configFileSpecs,
      getDirectoryPath(configFileName),
      config.parsedCommandLine.options,
      config.cachedDirectoryStructureHost,
      this.hostConfiguration.extraFileExtensions
    );
    config.parsedCommandLine = { ...config.parsedCommandLine, fileNames };
    return fileNames;
  }
  /** @internal */
  setFileNamesOfAutpImportProviderOrAuxillaryProject(project, fileNames) {
    this.updateNonInferredProjectFiles(project, fileNames, fileNamePropertyReader);
  }
  /** @internal */
  reloadConfiguredProjectClearingSemanticCache(project, reason, reloadedProjects) {
    if (!tryAddToSet(reloadedProjects, project)) return false;
    this.clearSemanticCache(project);
    this.reloadConfiguredProject(project, reloadReason(reason));
    return true;
  }
  /**
   * Read the config file of the project again by clearing the cache and update the project graph
   *
   * @internal
   */
  reloadConfiguredProject(project, reason) {
    project.isInitialLoadPending = returnFalse;
    project.pendingUpdateReason = void 0;
    project.pendingUpdateLevel = 0 /* Update */;
    const host = project.getCachedDirectoryStructureHost();
    host.clearCache();
    this.loadConfiguredProject(project, reason);
    updateWithTriggerFile(
      project,
      project.triggerFileForConfigFileDiag ?? project.getConfigFilePath(),
      /*isReload*/
      true
    );
  }
  clearSemanticCache(project) {
    project.originalConfiguredProjects = void 0;
    project.resolutionCache.clear();
    project.getLanguageService(
      /*ensureSynchronized*/
      false
    ).cleanupSemanticCache();
    project.cleanupProgram();
    project.markAsDirty();
  }
  /** @internal */
  sendConfigFileDiagEvent(project, triggerFile, force) {
    if (!this.eventHandler || this.suppressDiagnosticEvents) return false;
    const diagnostics = project.getLanguageService().getCompilerOptionsDiagnostics();
    diagnostics.push(...project.getAllProjectErrors());
    if (!force && diagnostics.length === (project.configDiagDiagnosticsReported ?? 0)) return false;
    project.configDiagDiagnosticsReported = diagnostics.length;
    this.eventHandler(
      {
        eventName: ConfigFileDiagEvent,
        data: { configFileName: project.getConfigFilePath(), diagnostics, triggerFile: triggerFile ?? project.getConfigFilePath() }
      }
    );
    return true;
  }
  getOrCreateInferredProjectForProjectRootPathIfEnabled(info, projectRootPath) {
    if (!this.useInferredProjectPerProjectRoot || // Its a dynamic info opened without project root
    info.isDynamic && projectRootPath === void 0) {
      return void 0;
    }
    if (projectRootPath) {
      const canonicalProjectRootPath = this.toCanonicalFileName(projectRootPath);
      for (const project of this.inferredProjects) {
        if (project.projectRootPath === canonicalProjectRootPath) {
          return project;
        }
      }
      return this.createInferredProject(
        projectRootPath,
        /*isSingleInferredProject*/
        false,
        projectRootPath
      );
    }
    let bestMatch;
    for (const project of this.inferredProjects) {
      if (!project.projectRootPath) continue;
      if (!containsPath(project.projectRootPath, info.path, this.host.getCurrentDirectory(), !this.host.useCaseSensitiveFileNames)) continue;
      if (bestMatch && bestMatch.projectRootPath.length > project.projectRootPath.length) continue;
      bestMatch = project;
    }
    return bestMatch;
  }
  getOrCreateSingleInferredProjectIfEnabled() {
    if (!this.useSingleInferredProject) {
      return void 0;
    }
    if (this.inferredProjects.length > 0 && this.inferredProjects[0].projectRootPath === void 0) {
      return this.inferredProjects[0];
    }
    return this.createInferredProject(
      "",
      /*isSingleInferredProject*/
      true
    );
  }
  getOrCreateSingleInferredWithoutProjectRoot(currentDirectory) {
    Debug.assert(!this.useSingleInferredProject);
    const expectedCurrentDirectory = this.toCanonicalFileName(this.getNormalizedAbsolutePath(currentDirectory));
    for (const inferredProject of this.inferredProjects) {
      if (!inferredProject.projectRootPath && inferredProject.isOrphan() && inferredProject.canonicalCurrentDirectory === expectedCurrentDirectory) {
        return inferredProject;
      }
    }
    return this.createInferredProject(currentDirectory);
  }
  createInferredProject(currentDirectory, isSingleInferredProject, projectRootPath) {
    const compilerOptions = projectRootPath && this.compilerOptionsForInferredProjectsPerProjectRoot.get(projectRootPath) || this.compilerOptionsForInferredProjects;
    let watchOptionsAndErrors;
    let typeAcquisition;
    if (projectRootPath) {
      watchOptionsAndErrors = this.watchOptionsForInferredProjectsPerProjectRoot.get(projectRootPath);
      typeAcquisition = this.typeAcquisitionForInferredProjectsPerProjectRoot.get(projectRootPath);
    }
    if (watchOptionsAndErrors === void 0) {
      watchOptionsAndErrors = this.watchOptionsForInferredProjects;
    }
    if (typeAcquisition === void 0) {
      typeAcquisition = this.typeAcquisitionForInferredProjects;
    }
    watchOptionsAndErrors = watchOptionsAndErrors || void 0;
    const project = new InferredProject2(this, this.documentRegistry, compilerOptions, watchOptionsAndErrors == null ? void 0 : watchOptionsAndErrors.watchOptions, projectRootPath, currentDirectory, typeAcquisition);
    project.setProjectErrors(watchOptionsAndErrors == null ? void 0 : watchOptionsAndErrors.errors);
    if (isSingleInferredProject) {
      this.inferredProjects.unshift(project);
    } else {
      this.inferredProjects.push(project);
    }
    return project;
  }
  /** @internal */
  getOrCreateScriptInfoNotOpenedByClient(uncheckedFileName, currentDirectory, hostToQueryFileExistsOn, deferredDeleteOk) {
    return this.getOrCreateScriptInfoNotOpenedByClientForNormalizedPath(
      toNormalizedPath(uncheckedFileName),
      currentDirectory,
      /*scriptKind*/
      void 0,
      /*hasMixedContent*/
      void 0,
      hostToQueryFileExistsOn,
      deferredDeleteOk
    );
  }
  getScriptInfo(uncheckedFileName) {
    return this.getScriptInfoForNormalizedPath(toNormalizedPath(uncheckedFileName));
  }
  /** @internal */
  getScriptInfoOrConfig(uncheckedFileName) {
    const path = toNormalizedPath(uncheckedFileName);
    const info = this.getScriptInfoForNormalizedPath(path);
    if (info) return info;
    const configProject = this.configuredProjects.get(this.toPath(uncheckedFileName));
    return configProject && configProject.getCompilerOptions().configFile;
  }
  /** @internal */
  logErrorForScriptInfoNotFound(fileName) {
    const names = arrayFrom(
      mapDefinedIterator(
        this.filenameToScriptInfo.entries(),
        (entry) => entry[1].deferredDelete ? void 0 : entry
      ),
      ([path, scriptInfo]) => ({ path, fileName: scriptInfo.fileName })
    );
    this.logger.msg(`Could not find file ${JSON.stringify(fileName)}.
All files are: ${JSON.stringify(names)}`, "Err" /* Err */);
  }
  /**
   * Returns the projects that contain script info through SymLink
   * Note that this does not return projects in info.containingProjects
   *
   * @internal
   */
  getSymlinkedProjects(info) {
    let projects;
    if (this.realpathToScriptInfos) {
      const realpath = info.getRealpathIfDifferent();
      if (realpath) {
        forEach(this.realpathToScriptInfos.get(realpath), combineProjects);
      }
      forEach(this.realpathToScriptInfos.get(info.path), combineProjects);
    }
    return projects;
    function combineProjects(toAddInfo) {
      if (toAddInfo !== info) {
        for (const project of toAddInfo.containingProjects) {
          if (project.languageServiceEnabled && !project.isOrphan() && !project.getCompilerOptions().preserveSymlinks && !info.isAttached(project)) {
            if (!projects) {
              projects = createMultiMap();
              projects.add(toAddInfo.path, project);
            } else if (!forEachEntry(projects, (projs, path) => path === toAddInfo.path ? false : contains(projs, project))) {
              projects.add(toAddInfo.path, project);
            }
          }
        }
      }
    }
  }
  watchClosedScriptInfo(info) {
    Debug.assert(!info.fileWatcher);
    if (!info.isDynamicOrHasMixedContent() && (!this.globalCacheLocationDirectoryPath || !startsWith(info.path, this.globalCacheLocationDirectoryPath))) {
      const indexOfNodeModules = info.fileName.indexOf("/node_modules/");
      if (!this.host.getModifiedTime || indexOfNodeModules === -1) {
        info.fileWatcher = this.watchFactory.watchFile(
          info.fileName,
          (_fileName, eventKind) => this.onSourceFileChanged(info, eventKind),
          500 /* Medium */,
          this.hostConfiguration.watchOptions,
          WatchType.ClosedScriptInfo
        );
      } else {
        info.mTime = this.getModifiedTime(info);
        info.fileWatcher = this.watchClosedScriptInfoInNodeModules(info.fileName.substring(0, indexOfNodeModules));
      }
    }
  }
  createNodeModulesWatcher(dir, dirPath) {
    let watcher = this.watchFactory.watchDirectory(
      dir,
      (fileOrDirectory) => {
        var _a;
        const fileOrDirectoryPath = removeIgnoredPath(this.toPath(fileOrDirectory));
        if (!fileOrDirectoryPath) return;
        const basename = getBaseFileName(fileOrDirectoryPath);
        if (((_a = result.affectedModuleSpecifierCacheProjects) == null ? void 0 : _a.size) && (basename === "package.json" || basename === "node_modules")) {
          result.affectedModuleSpecifierCacheProjects.forEach((project) => {
            var _a2;
            (_a2 = project.getModuleSpecifierCache()) == null ? void 0 : _a2.clear();
          });
        }
        if (result.refreshScriptInfoRefCount) {
          if (dirPath === fileOrDirectoryPath) {
            this.refreshScriptInfosInDirectory(dirPath);
          } else {
            const info = this.filenameToScriptInfo.get(fileOrDirectoryPath);
            if (info) {
              if (isScriptInfoWatchedFromNodeModules(info)) {
                this.refreshScriptInfo(info);
              }
            } else if (!hasExtension(fileOrDirectoryPath)) {
              this.refreshScriptInfosInDirectory(fileOrDirectoryPath);
            }
          }
        }
      },
      1 /* Recursive */,
      this.hostConfiguration.watchOptions,
      WatchType.NodeModules
    );
    const result = {
      refreshScriptInfoRefCount: 0,
      affectedModuleSpecifierCacheProjects: void 0,
      close: () => {
        var _a;
        if (watcher && !result.refreshScriptInfoRefCount && !((_a = result.affectedModuleSpecifierCacheProjects) == null ? void 0 : _a.size)) {
          watcher.close();
          watcher = void 0;
          this.nodeModulesWatchers.delete(dirPath);
        }
      }
    };
    this.nodeModulesWatchers.set(dirPath, result);
    return result;
  }
  /** @internal */
  watchPackageJsonsInNodeModules(dir, project) {
    var _a;
    const dirPath = this.toPath(dir);
    const watcher = this.nodeModulesWatchers.get(dirPath) || this.createNodeModulesWatcher(dir, dirPath);
    Debug.assert(!((_a = watcher.affectedModuleSpecifierCacheProjects) == null ? void 0 : _a.has(project)));
    (watcher.affectedModuleSpecifierCacheProjects || (watcher.affectedModuleSpecifierCacheProjects = /* @__PURE__ */ new Set())).add(project);
    return {
      close: () => {
        var _a2;
        (_a2 = watcher.affectedModuleSpecifierCacheProjects) == null ? void 0 : _a2.delete(project);
        watcher.close();
      }
    };
  }
  watchClosedScriptInfoInNodeModules(dir) {
    const watchDir = dir + "/node_modules";
    const watchDirPath = this.toPath(watchDir);
    const watcher = this.nodeModulesWatchers.get(watchDirPath) || this.createNodeModulesWatcher(watchDir, watchDirPath);
    watcher.refreshScriptInfoRefCount++;
    return {
      close: () => {
        watcher.refreshScriptInfoRefCount--;
        watcher.close();
      }
    };
  }
  getModifiedTime(info) {
    return (this.host.getModifiedTime(info.fileName) || missingFileModifiedTime).getTime();
  }
  refreshScriptInfo(info) {
    const mTime = this.getModifiedTime(info);
    if (mTime !== info.mTime) {
      const eventKind = getFileWatcherEventKind(info.mTime, mTime);
      info.mTime = mTime;
      this.onSourceFileChanged(info, eventKind);
    }
  }
  refreshScriptInfosInDirectory(dir) {
    dir = dir + directorySeparator;
    this.filenameToScriptInfo.forEach((info) => {
      if (isScriptInfoWatchedFromNodeModules(info) && startsWith(info.path, dir)) {
        this.refreshScriptInfo(info);
      }
    });
  }
  stopWatchingScriptInfo(info) {
    if (info.fileWatcher) {
      info.fileWatcher.close();
      info.fileWatcher = void 0;
    }
  }
  getOrCreateScriptInfoNotOpenedByClientForNormalizedPath(fileName, currentDirectory, scriptKind, hasMixedContent, hostToQueryFileExistsOn, deferredDeleteOk) {
    if (isRootedDiskPath(fileName) || isDynamicFileName(fileName)) {
      return this.getOrCreateScriptInfoWorker(
        fileName,
        currentDirectory,
        /*openedByClient*/
        false,
        /*fileContent*/
        void 0,
        scriptKind,
        !!hasMixedContent,
        hostToQueryFileExistsOn,
        deferredDeleteOk
      );
    }
    const info = this.openFilesWithNonRootedDiskPath.get(this.toCanonicalFileName(fileName));
    if (info) {
      return info;
    }
    return void 0;
  }
  getOrCreateScriptInfoForNormalizedPath(fileName, openedByClient, fileContent, scriptKind, hasMixedContent, hostToQueryFileExistsOn) {
    return this.getOrCreateScriptInfoWorker(
      fileName,
      this.currentDirectory,
      openedByClient,
      fileContent,
      scriptKind,
      !!hasMixedContent,
      hostToQueryFileExistsOn,
      /*deferredDeleteOk*/
      false
    );
  }
  getOrCreateScriptInfoWorker(fileName, currentDirectory, openedByClient, fileContent, scriptKind, hasMixedContent, hostToQueryFileExistsOn, deferredDeleteOk) {
    Debug.assert(fileContent === void 0 || openedByClient, "ScriptInfo needs to be opened by client to be able to set its user defined content");
    const path = normalizedPathToPath(fileName, currentDirectory, this.toCanonicalFileName);
    let info = this.filenameToScriptInfo.get(path);
    if (!info) {
      const isDynamic = isDynamicFileName(fileName);
      Debug.assert(isRootedDiskPath(fileName) || isDynamic || openedByClient, "", () => `${JSON.stringify({ fileName, currentDirectory, hostCurrentDirectory: this.currentDirectory, openKeys: arrayFrom(this.openFilesWithNonRootedDiskPath.keys()) })}
Script info with non-dynamic relative file name can only be open script info or in context of host currentDirectory`);
      Debug.assert(!isRootedDiskPath(fileName) || this.currentDirectory === currentDirectory || !this.openFilesWithNonRootedDiskPath.has(this.toCanonicalFileName(fileName)), "", () => `${JSON.stringify({ fileName, currentDirectory, hostCurrentDirectory: this.currentDirectory, openKeys: arrayFrom(this.openFilesWithNonRootedDiskPath.keys()) })}
Open script files with non rooted disk path opened with current directory context cannot have same canonical names`);
      Debug.assert(!isDynamic || this.currentDirectory === currentDirectory || this.useInferredProjectPerProjectRoot, "", () => `${JSON.stringify({ fileName, currentDirectory, hostCurrentDirectory: this.currentDirectory, openKeys: arrayFrom(this.openFilesWithNonRootedDiskPath.keys()) })}
Dynamic files must always be opened with service's current directory or service should support inferred project per projectRootPath.`);
      if (!openedByClient && !isDynamic && !(hostToQueryFileExistsOn || this.host).fileExists(fileName)) {
        return;
      }
      info = new ScriptInfo(this.host, fileName, scriptKind, hasMixedContent, path, this.filenameToScriptInfoVersion.get(path));
      this.filenameToScriptInfo.set(info.path, info);
      this.filenameToScriptInfoVersion.delete(info.path);
      if (!openedByClient) {
        this.watchClosedScriptInfo(info);
      } else if (!isRootedDiskPath(fileName) && (!isDynamic || this.currentDirectory !== currentDirectory)) {
        this.openFilesWithNonRootedDiskPath.set(this.toCanonicalFileName(fileName), info);
      }
    } else if (info.deferredDelete) {
      Debug.assert(!info.isDynamic);
      if (!openedByClient && !(hostToQueryFileExistsOn || this.host).fileExists(fileName)) {
        return deferredDeleteOk ? info : void 0;
      }
      info.deferredDelete = void 0;
    }
    if (openedByClient) {
      this.stopWatchingScriptInfo(info);
      info.open(fileContent);
      if (hasMixedContent) {
        info.registerFileUpdate();
      }
    }
    return info;
  }
  /**
   * This gets the script info for the normalized path. If the path is not rooted disk path then the open script info with project root context is preferred
   */
  getScriptInfoForNormalizedPath(fileName) {
    return !isRootedDiskPath(fileName) && this.openFilesWithNonRootedDiskPath.get(this.toCanonicalFileName(fileName)) || this.getScriptInfoForPath(normalizedPathToPath(fileName, this.currentDirectory, this.toCanonicalFileName));
  }
  getScriptInfoForPath(fileName) {
    const info = this.filenameToScriptInfo.get(fileName);
    return !info || !info.deferredDelete ? info : void 0;
  }
  /** @internal */
  getDocumentPositionMapper(project, generatedFileName, sourceFileName) {
    const declarationInfo = this.getOrCreateScriptInfoNotOpenedByClient(
      generatedFileName,
      project.currentDirectory,
      this.host,
      /*deferredDeleteOk*/
      false
    );
    if (!declarationInfo) {
      if (sourceFileName) {
        project.addGeneratedFileWatch(generatedFileName, sourceFileName);
      }
      return void 0;
    }
    declarationInfo.getSnapshot();
    if (isString(declarationInfo.sourceMapFilePath)) {
      const sourceMapFileInfo2 = this.getScriptInfoForPath(declarationInfo.sourceMapFilePath);
      if (sourceMapFileInfo2) {
        sourceMapFileInfo2.getSnapshot();
        if (sourceMapFileInfo2.documentPositionMapper !== void 0) {
          sourceMapFileInfo2.sourceInfos = this.addSourceInfoToSourceMap(sourceFileName, project, sourceMapFileInfo2.sourceInfos);
          return sourceMapFileInfo2.documentPositionMapper ? sourceMapFileInfo2.documentPositionMapper : void 0;
        }
      }
      declarationInfo.sourceMapFilePath = void 0;
    } else if (declarationInfo.sourceMapFilePath) {
      declarationInfo.sourceMapFilePath.sourceInfos = this.addSourceInfoToSourceMap(sourceFileName, project, declarationInfo.sourceMapFilePath.sourceInfos);
      return void 0;
    } else if (declarationInfo.sourceMapFilePath !== void 0) {
      return void 0;
    }
    let sourceMapFileInfo;
    let readMapFile = (mapFileName, mapFileNameFromDts) => {
      const mapInfo = this.getOrCreateScriptInfoNotOpenedByClient(
        mapFileName,
        project.currentDirectory,
        this.host,
        /*deferredDeleteOk*/
        true
      );
      sourceMapFileInfo = mapInfo || mapFileNameFromDts;
      if (!mapInfo || mapInfo.deferredDelete) return void 0;
      const snap = mapInfo.getSnapshot();
      if (mapInfo.documentPositionMapper !== void 0) return mapInfo.documentPositionMapper;
      return getSnapshotText(snap);
    };
    const projectName = project.projectName;
    const documentPositionMapper = getDocumentPositionMapper(
      { getCanonicalFileName: this.toCanonicalFileName, log: (s) => this.logger.info(s), getSourceFileLike: (f) => this.getSourceFileLike(f, projectName, declarationInfo) },
      declarationInfo.fileName,
      declarationInfo.textStorage.getLineInfo(),
      readMapFile
    );
    readMapFile = void 0;
    if (sourceMapFileInfo) {
      if (!isString(sourceMapFileInfo)) {
        declarationInfo.sourceMapFilePath = sourceMapFileInfo.path;
        sourceMapFileInfo.declarationInfoPath = declarationInfo.path;
        if (!sourceMapFileInfo.deferredDelete) sourceMapFileInfo.documentPositionMapper = documentPositionMapper || false;
        sourceMapFileInfo.sourceInfos = this.addSourceInfoToSourceMap(sourceFileName, project, sourceMapFileInfo.sourceInfos);
      } else {
        declarationInfo.sourceMapFilePath = {
          watcher: this.addMissingSourceMapFile(
            project.currentDirectory === this.currentDirectory ? sourceMapFileInfo : getNormalizedAbsolutePath(sourceMapFileInfo, project.currentDirectory),
            declarationInfo.path
          ),
          sourceInfos: this.addSourceInfoToSourceMap(sourceFileName, project)
        };
      }
    } else {
      declarationInfo.sourceMapFilePath = false;
    }
    return documentPositionMapper;
  }
  addSourceInfoToSourceMap(sourceFileName, project, sourceInfos) {
    if (sourceFileName) {
      const sourceInfo = this.getOrCreateScriptInfoNotOpenedByClient(
        sourceFileName,
        project.currentDirectory,
        project.directoryStructureHost,
        /*deferredDeleteOk*/
        false
      );
      (sourceInfos || (sourceInfos = /* @__PURE__ */ new Set())).add(sourceInfo.path);
    }
    return sourceInfos;
  }
  addMissingSourceMapFile(mapFileName, declarationInfoPath) {
    const fileWatcher = this.watchFactory.watchFile(
      mapFileName,
      () => {
        const declarationInfo = this.getScriptInfoForPath(declarationInfoPath);
        if (declarationInfo && declarationInfo.sourceMapFilePath && !isString(declarationInfo.sourceMapFilePath)) {
          this.delayUpdateProjectGraphs(
            declarationInfo.containingProjects,
            /*clearSourceMapperCache*/
            true
          );
          this.delayUpdateSourceInfoProjects(declarationInfo.sourceMapFilePath.sourceInfos);
          declarationInfo.closeSourceMapFileWatcher();
        }
      },
      2e3 /* High */,
      this.hostConfiguration.watchOptions,
      WatchType.MissingSourceMapFile
    );
    return fileWatcher;
  }
  /** @internal */
  getSourceFileLike(fileName, projectNameOrProject, declarationInfo) {
    const project = projectNameOrProject.projectName ? projectNameOrProject : this.findProject(projectNameOrProject);
    if (project) {
      const path = project.toPath(fileName);
      const sourceFile = project.getSourceFile(path);
      if (sourceFile && sourceFile.resolvedPath === path) return sourceFile;
    }
    const info = this.getOrCreateScriptInfoNotOpenedByClient(
      fileName,
      (project || this).currentDirectory,
      project ? project.directoryStructureHost : this.host,
      /*deferredDeleteOk*/
      false
    );
    if (!info) return void 0;
    if (declarationInfo && isString(declarationInfo.sourceMapFilePath) && info !== declarationInfo) {
      const sourceMapInfo = this.getScriptInfoForPath(declarationInfo.sourceMapFilePath);
      if (sourceMapInfo) {
        (sourceMapInfo.sourceInfos ?? (sourceMapInfo.sourceInfos = /* @__PURE__ */ new Set())).add(info.path);
      }
    }
    if (info.cacheSourceFile) return info.cacheSourceFile.sourceFile;
    if (!info.sourceFileLike) {
      info.sourceFileLike = {
        get text() {
          Debug.fail("shouldnt need text");
          return "";
        },
        getLineAndCharacterOfPosition: (pos) => {
          const lineOffset = info.positionToLineOffset(pos);
          return { line: lineOffset.line - 1, character: lineOffset.offset - 1 };
        },
        getPositionOfLineAndCharacter: (line, character, allowEdits) => info.lineOffsetToPosition(line + 1, character + 1, allowEdits)
      };
    }
    return info.sourceFileLike;
  }
  /** @internal */
  setPerformanceEventHandler(performanceEventHandler) {
    this.performanceEventHandler = performanceEventHandler;
  }
  setHostConfiguration(args) {
    var _a, _b;
    if (args.file) {
      const info = this.getScriptInfoForNormalizedPath(toNormalizedPath(args.file));
      if (info) {
        info.setOptions(convertFormatOptions(args.formatOptions), args.preferences);
        this.logger.info(`Host configuration update for file ${args.file}`);
      }
    } else {
      if (args.hostInfo !== void 0) {
        this.hostConfiguration.hostInfo = args.hostInfo;
        this.logger.info(`Host information ${args.hostInfo}`);
      }
      if (args.formatOptions) {
        this.hostConfiguration.formatCodeOptions = { ...this.hostConfiguration.formatCodeOptions, ...convertFormatOptions(args.formatOptions) };
        this.logger.info("Format host information updated");
      }
      if (args.preferences) {
        const {
          lazyConfiguredProjectsFromExternalProject,
          includePackageJsonAutoImports,
          includeCompletionsForModuleExports
        } = this.hostConfiguration.preferences;
        this.hostConfiguration.preferences = { ...this.hostConfiguration.preferences, ...args.preferences };
        if (lazyConfiguredProjectsFromExternalProject && !this.hostConfiguration.preferences.lazyConfiguredProjectsFromExternalProject) {
          this.externalProjectToConfiguredProjectMap.forEach(
            (projects) => projects.forEach((project) => {
              if (!project.deferredClose && !project.isClosed() && project.pendingUpdateLevel === 2 /* Full */ && !this.hasPendingProjectUpdate(project)) {
                project.updateGraph();
              }
            })
          );
        }
        if (includePackageJsonAutoImports !== args.preferences.includePackageJsonAutoImports || !!includeCompletionsForModuleExports !== !!args.preferences.includeCompletionsForModuleExports) {
          this.forEachProject((project) => {
            project.onAutoImportProviderSettingsChanged();
          });
        }
      }
      if (args.extraFileExtensions) {
        this.hostConfiguration.extraFileExtensions = args.extraFileExtensions;
        this.reloadProjects();
        this.logger.info("Host file extension mappings updated");
      }
      if (args.watchOptions) {
        const watchOptions = (_a = convertWatchOptions(args.watchOptions)) == null ? void 0 : _a.watchOptions;
        const substitution = handleWatchOptionsConfigDirTemplateSubstitution(watchOptions, this.currentDirectory);
        this.hostConfiguration.watchOptions = substitution;
        this.hostConfiguration.beforeSubstitution = substitution === watchOptions ? void 0 : watchOptions;
        this.logger.info(`Host watch options changed to ${JSON.stringify(this.hostConfiguration.watchOptions)}, it will be take effect for next watches.`);
        (_b = this.pnpWatcher) == null ? void 0 : _b.close();
        this.watchPnpFile();
      }
    }
  }
  /** @internal */
  getWatchOptions(project) {
    return this.getWatchOptionsFromProjectWatchOptions(project.getWatchOptions(), project.getCurrentDirectory());
  }
  getWatchOptionsFromProjectWatchOptions(projectOptions, basePath) {
    const hostWatchOptions = !this.hostConfiguration.beforeSubstitution ? this.hostConfiguration.watchOptions : handleWatchOptionsConfigDirTemplateSubstitution(
      this.hostConfiguration.beforeSubstitution,
      basePath
    );
    return projectOptions && hostWatchOptions ? { ...hostWatchOptions, ...projectOptions } : projectOptions || hostWatchOptions;
  }
  closeLog() {
    this.logger.close();
  }
  sendSourceFileChange(inPath) {
    this.filenameToScriptInfo.forEach((info) => {
      if (this.openFiles.has(info.path)) return;
      if (!info.fileWatcher) return;
      const eventKind = memoize(
        () => this.host.fileExists(info.fileName) ? info.deferredDelete ? 0 /* Created */ : 1 /* Changed */ : 2 /* Deleted */
      );
      if (inPath) {
        if (isScriptInfoWatchedFromNodeModules(info) || !info.path.startsWith(inPath)) return;
        if (eventKind() === 2 /* Deleted */ && info.deferredDelete) return;
        this.logger.info(`Invoking sourceFileChange on ${info.fileName}:: ${eventKind()}`);
      }
      this.onSourceFileChanged(
        info,
        eventKind()
      );
    });
  }
  /**
   * This function rebuilds the project for every file opened by the client
   * This does not reload contents of open files from disk. But we could do that if needed
   */
  reloadProjects() {
    this.logger.info("reload projects.");
    this.sendSourceFileChange(
      /*inPath*/
      void 0
    );
    this.pendingProjectUpdates.forEach((_project, projectName) => {
      this.throttledOperations.cancel(projectName);
      this.pendingProjectUpdates.delete(projectName);
    });
    this.throttledOperations.cancel(ensureProjectForOpenFileSchedule);
    this.pendingOpenFileProjectUpdates = void 0;
    this.pendingEnsureProjectForOpenFiles = false;
    this.configFileExistenceInfoCache.forEach((info) => {
      if (info.config) info.config.updateLevel = 2 /* Full */;
    });
    this.configFileForOpenFiles.clear();
    this.externalProjects.forEach((project) => {
      this.clearSemanticCache(project);
      project.updateGraph();
    });
    const reloadedConfiguredProjects = /* @__PURE__ */ new Set();
    const delayReloadedConfiguredProjects = /* @__PURE__ */ new Set();
    this.externalProjectToConfiguredProjectMap.forEach((projects, externalProjectName) => {
      const reason = `Reloading configured project in external project: ${externalProjectName}`;
      projects.forEach((project) => {
        if (this.getHostPreferences().lazyConfiguredProjectsFromExternalProject) {
          if (!project.isInitialLoadPending()) {
            this.clearSemanticCache(project);
            project.pendingUpdateLevel = 2 /* Full */;
            project.pendingUpdateReason = reloadReason(reason);
          }
          delayReloadedConfiguredProjects.add(project);
        } else {
          this.reloadConfiguredProjectClearingSemanticCache(
            project,
            reason,
            reloadedConfiguredProjects
          );
        }
      });
    });
    this.openFiles.forEach((_projectRootPath, path) => {
      const info = this.getScriptInfoForPath(path);
      if (find(info.containingProjects, isExternalProject)) return;
      this.tryFindDefaultConfiguredProjectAndLoadAncestorsForOpenScriptInfo(
        info,
        2 /* Reload */,
        reloadedConfiguredProjects,
        delayReloadedConfiguredProjects
      );
    });
    delayReloadedConfiguredProjects.forEach((p) => reloadedConfiguredProjects.add(p));
    this.inferredProjects.forEach((project) => this.clearSemanticCache(project));
    this.ensureProjectForOpenFiles();
    this.cleanupProjectsAndScriptInfos(
      reloadedConfiguredProjects,
      new Set(this.openFiles.keys()),
      new Set(this.externalProjectToConfiguredProjectMap.keys())
    );
    this.logger.info("After reloading projects..");
    this.printProjects();
  }
  /**
   * Remove the root of inferred project if script info is part of another project
   */
  removeRootOfInferredProjectIfNowPartOfOtherProject(info) {
    Debug.assert(info.containingProjects.length > 0);
    const firstProject = info.containingProjects[0];
    if (!firstProject.isOrphan() && isInferredProject(firstProject) && firstProject.isRoot(info) && forEach(info.containingProjects, (p) => p !== firstProject && !p.isOrphan())) {
      firstProject.removeFile(
        info,
        /*fileExists*/
        true,
        /*detachFromProject*/
        true
      );
    }
  }
  /**
   * This function is to update the project structure for every inferred project.
   * It is called on the premise that all the configured projects are
   * up to date.
   * This will go through open files and assign them to inferred project if open file is not part of any other project
   * After that all the inferred project graphs are updated
   */
  ensureProjectForOpenFiles() {
    this.logger.info("Before ensureProjectForOpenFiles:");
    this.printProjects();
    const pendingOpenFileProjectUpdates = this.pendingOpenFileProjectUpdates;
    this.pendingOpenFileProjectUpdates = void 0;
    pendingOpenFileProjectUpdates == null ? void 0 : pendingOpenFileProjectUpdates.forEach(
      (_config, path) => this.tryFindDefaultConfiguredProjectAndLoadAncestorsForOpenScriptInfo(
        this.getScriptInfoForPath(path),
        1 /* Create */
      )
    );
    this.openFiles.forEach((projectRootPath, path) => {
      const info = this.getScriptInfoForPath(path);
      if (info.isOrphan()) {
        this.assignOrphanScriptInfoToInferredProject(info, projectRootPath);
      } else {
        this.removeRootOfInferredProjectIfNowPartOfOtherProject(info);
      }
    });
    this.pendingEnsureProjectForOpenFiles = false;
    this.inferredProjects.forEach(updateProjectIfDirty);
    this.logger.info("After ensureProjectForOpenFiles:");
    this.printProjects();
  }
  /**
   * Open file whose contents is managed by the client
   * @param filename is absolute pathname
   * @param fileContent is a known version of the file content that is more up to date than the one on disk
   */
  openClientFile(fileName, fileContent, scriptKind, projectRootPath) {
    return this.openClientFileWithNormalizedPath(
      toNormalizedPath(fileName),
      fileContent,
      scriptKind,
      /*hasMixedContent*/
      false,
      projectRootPath ? toNormalizedPath(projectRootPath) : void 0
    );
  }
  /** @internal */
  getOriginalLocationEnsuringConfiguredProject(project, location) {
    const isSourceOfProjectReferenceRedirect = project.isSourceOfProjectReferenceRedirect(location.fileName);
    const originalLocation = isSourceOfProjectReferenceRedirect ? location : project.getSourceMapper().tryGetSourcePosition(location);
    if (!originalLocation) return void 0;
    const { fileName } = originalLocation;
    const scriptInfo = this.getScriptInfo(fileName);
    if (!scriptInfo && !this.host.fileExists(fileName)) return void 0;
    const originalFileInfo = { fileName: toNormalizedPath(fileName), path: this.toPath(fileName) };
    const configFileName = this.getConfigFileNameForFile(
      originalFileInfo,
      /*findFromCacheOnly*/
      false
    );
    if (!configFileName) return void 0;
    let configuredProject = this.findConfiguredProjectByProjectName(configFileName);
    if (!configuredProject) {
      if (project.getCompilerOptions().disableReferencedProjectLoad) {
        if (isSourceOfProjectReferenceRedirect) {
          return location;
        }
        return (scriptInfo == null ? void 0 : scriptInfo.containingProjects.length) ? originalLocation : location;
      }
      configuredProject = this.createConfiguredProject(configFileName, `Creating project for original file: ${originalFileInfo.fileName}${location !== originalLocation ? " for location: " + location.fileName : ""}`);
    }
    updateProjectIfDirty(configuredProject);
    const projectContainsOriginalInfo = (project2) => {
      const info = this.getScriptInfo(fileName);
      return info && project2.containsScriptInfo(info) && !project2.isSourceOfProjectReferenceRedirect(info.path);
    };
    if (configuredProject.isSolution() || !projectContainsOriginalInfo(configuredProject)) {
      configuredProject = forEachResolvedProjectReferenceProject(
        configuredProject,
        fileName,
        (child) => projectContainsOriginalInfo(child) ? child : void 0,
        1 /* Create */,
        `Creating project referenced in solution ${configuredProject.projectName} to find possible configured project for original file: ${originalFileInfo.fileName}${location !== originalLocation ? " for location: " + location.fileName : ""}`
      );
      if (!configuredProject) return void 0;
      if (configuredProject === project) return originalLocation;
    }
    addOriginalConfiguredProject(configuredProject);
    const originalScriptInfo = this.getScriptInfo(fileName);
    if (!originalScriptInfo || !originalScriptInfo.containingProjects.length) return void 0;
    originalScriptInfo.containingProjects.forEach((project2) => {
      if (isConfiguredProject(project2)) {
        addOriginalConfiguredProject(project2);
      }
    });
    return originalLocation;
    function addOriginalConfiguredProject(originalProject) {
      (project.originalConfiguredProjects ?? (project.originalConfiguredProjects = /* @__PURE__ */ new Set())).add(originalProject.canonicalConfigFilePath);
    }
  }
  /** @internal */
  fileExists(fileName) {
    return !!this.getScriptInfoForNormalizedPath(fileName) || this.host.fileExists(fileName);
  }
  findExternalProjectContainingOpenScriptInfo(info) {
    return find(this.externalProjects, (proj) => {
      updateProjectIfDirty(proj);
      return proj.containsScriptInfo(info);
    });
  }
  getOrCreateOpenScriptInfo(fileName, fileContent, scriptKind, hasMixedContent, projectRootPath) {
    const info = this.getOrCreateScriptInfoWorker(
      fileName,
      projectRootPath ? this.getNormalizedAbsolutePath(projectRootPath) : this.currentDirectory,
      /*openedByClient*/
      true,
      fileContent,
      scriptKind,
      !!hasMixedContent,
      /*hostToQueryFileExistsOn*/
      void 0,
      /*deferredDeleteOk*/
      true
    );
    this.openFiles.set(info.path, projectRootPath);
    return info;
  }
  assignProjectToOpenedScriptInfo(info) {
    let configFileName;
    let configFileErrors;
    const project = this.findExternalProjectContainingOpenScriptInfo(info);
    let retainProjects;
    let sentConfigDiag;
    if (!project && this.serverMode === 0 /* Semantic */) {
      const result = this.tryFindDefaultConfiguredProjectAndLoadAncestorsForOpenScriptInfo(
        info,
        1 /* Create */
      );
      if (result) {
        retainProjects = result.seenProjects;
        sentConfigDiag = result.sentConfigDiag;
        if (result.defaultProject) {
          configFileName = result.defaultProject.getConfigFilePath();
          configFileErrors = result.defaultProject.getAllProjectErrors();
        }
      }
    }
    info.containingProjects.forEach(updateProjectIfDirty);
    if (info.isOrphan()) {
      retainProjects == null ? void 0 : retainProjects.forEach((project2) => {
        if (!sentConfigDiag.has(project2)) this.sendConfigFileDiagEvent(
          project2,
          info.fileName,
          /*force*/
          true
        );
      });
      Debug.assert(this.openFiles.has(info.path));
      this.assignOrphanScriptInfoToInferredProject(info, this.openFiles.get(info.path));
    }
    Debug.assert(!info.isOrphan());
    return { configFileName, configFileErrors, retainProjects };
  }
  /**
   * Depending on kind
   * - Find the configuedProject and return it - if allowDeferredClosed is set it will find the deferredClosed project as well
   * - Create - if the project doesnt exist, it creates one as well. If not delayLoad, the project is updated (with triggerFile if passed)
   * - Reload - if the project doesnt exist, it creates one. If not delayLoad, the project is reloaded clearing semantic cache
   *  @internal
   */
  findCreateOrReloadConfiguredProject(configFileName, kind, reason, allowDeferredClosed, triggerFile, reloadedProjects, delayLoad, delayReloadedConfiguredProjects) {
    let project = this.findConfiguredProjectByProjectName(configFileName, allowDeferredClosed);
    let sentConfigFileDiag = false;
    switch (kind) {
      case 0 /* Find */:
        if (!project) return;
        break;
      case 1 /* Create */:
        project ?? (project = this.createConfiguredProject(configFileName, reason));
        sentConfigFileDiag = !delayLoad && updateConfiguredProject(project, triggerFile);
        break;
      case 2 /* Reload */:
        project ?? (project = this.createConfiguredProject(configFileName, reloadReason(reason)));
        sentConfigFileDiag = !delayReloadedConfiguredProjects && this.reloadConfiguredProjectClearingSemanticCache(project, reason, reloadedProjects);
        if (delayReloadedConfiguredProjects && !delayReloadedConfiguredProjects.has(project) && !reloadedProjects.has(project)) {
          project.pendingUpdateLevel = 2 /* Full */;
          project.pendingUpdateReason = reloadReason(reason);
          delayReloadedConfiguredProjects.add(project);
        }
        break;
      default:
        Debug.assertNever(kind);
    }
    return { project, sentConfigFileDiag };
  }
  /**
   * Finds the default configured project for given info
   * For any tsconfig found, it looks into that project, if not then all its references,
   * The search happens for all tsconfigs till projectRootPath
   */
  tryFindDefaultConfiguredProjectForOpenScriptInfo(info, kind, allowDeferredClosed, reloadedProjects) {
    const configFileName = this.getConfigFileNameForFile(info, kind === 0 /* Find */);
    if (!configFileName) return;
    const result = this.findCreateOrReloadConfiguredProject(
      configFileName,
      kind,
      fileOpenReason(info),
      allowDeferredClosed,
      info.fileName,
      reloadedProjects
    );
    if (!result) return;
    const seenProjects = /* @__PURE__ */ new Set();
    const sentConfigDiag = new Set(result.sentConfigFileDiag ? [result.project] : void 0);
    let defaultProject;
    let possiblyDefault;
    tryFindDefaultConfiguredProject(result.project);
    return {
      defaultProject: defaultProject ?? possiblyDefault,
      sentConfigDiag,
      seenProjects
    };
    function tryFindDefaultConfiguredProject(project) {
      return isDefaultProject(project) ? defaultProject : tryFindDefaultConfiguredProjectFromReferences(project);
    }
    function isDefaultProject(project) {
      if (!tryAddToSet(seenProjects, project)) return;
      const projectWithInfo = project.containsScriptInfo(info);
      if (projectWithInfo && !project.isSourceOfProjectReferenceRedirect(info.path)) return defaultProject = project;
      possiblyDefault ?? (possiblyDefault = projectWithInfo ? project : void 0);
    }
    function tryFindDefaultConfiguredProjectFromReferences(project) {
      return forEachResolvedProjectReferenceProject(
        project,
        info.path,
        (child, sentConfigFileDiag) => {
          if (sentConfigFileDiag) sentConfigDiag.add(child);
          return isDefaultProject(child);
        },
        kind,
        `Creating project referenced in solution ${project.projectName} to find possible configured project for ${info.fileName} to open`,
        allowDeferredClosed,
        info.fileName,
        reloadedProjects
      );
    }
  }
  tryFindDefaultConfiguredProjectAndLoadAncestorsForOpenScriptInfo(info, kind, reloadedProjects, delayReloadedConfiguredProjects) {
    const allowDeferredClosed = kind === 0 /* Find */;
    const result = this.tryFindDefaultConfiguredProjectForOpenScriptInfo(
      info,
      kind,
      allowDeferredClosed,
      reloadedProjects
    );
    if (!result) return;
    const { defaultProject, seenProjects } = result;
    if (defaultProject) {
      forEachAncestorProject(
        info,
        defaultProject,
        (ancestor) => {
          seenProjects.add(ancestor);
        },
        kind,
        `Creating project possibly referencing default composite project ${defaultProject.getProjectName()} of open file ${info.fileName}`,
        allowDeferredClosed,
        reloadedProjects,
        delayReloadedConfiguredProjects
      );
    }
    return result;
  }
  /** @internal */
  loadAncestorProjectTree(forProjects) {
    forProjects ?? (forProjects = new Set(
      mapDefinedIterator(this.configuredProjects.entries(), ([key, project]) => !project.isInitialLoadPending() ? key : void 0)
    ));
    const seenProjects = /* @__PURE__ */ new Set();
    const currentConfiguredProjects = arrayFrom(this.configuredProjects.values());
    for (const project of currentConfiguredProjects) {
      if (forEachPotentialProjectReference(project, (potentialRefPath) => forProjects.has(potentialRefPath))) {
        updateProjectIfDirty(project);
      }
      this.ensureProjectChildren(project, forProjects, seenProjects);
    }
  }
  ensureProjectChildren(project, forProjects, seenProjects) {
    var _a;
    if (!tryAddToSet(seenProjects, project.canonicalConfigFilePath)) return;
    if (project.getCompilerOptions().disableReferencedProjectLoad) return;
    const children = (_a = project.getCurrentProgram()) == null ? void 0 : _a.getResolvedProjectReferences();
    if (!children) return;
    for (const child of children) {
      if (!child) continue;
      const referencedProject = forEachResolvedProjectReference(child.references, (ref) => forProjects.has(ref.sourceFile.path) ? ref : void 0);
      if (!referencedProject) continue;
      const configFileName = toNormalizedPath(child.sourceFile.fileName);
      const childProject = this.findConfiguredProjectByProjectName(configFileName) ?? this.createConfiguredProject(
        configFileName,
        `Creating project referenced by : ${project.projectName} as it references project ${referencedProject.sourceFile.fileName}`
      );
      updateProjectIfDirty(childProject);
      this.ensureProjectChildren(childProject, forProjects, seenProjects);
    }
  }
  cleanupConfiguredProjects(toRetainConfiguredProjects, externalProjectsRetainingConfiguredProjects, openFilesWithRetainedConfiguredProject) {
    this.getOrphanConfiguredProjects(
      toRetainConfiguredProjects,
      openFilesWithRetainedConfiguredProject,
      externalProjectsRetainingConfiguredProjects
    ).forEach((project) => this.removeProject(project));
  }
  cleanupProjectsAndScriptInfos(toRetainConfiguredProjects, openFilesWithRetainedConfiguredProject, externalProjectsRetainingConfiguredProjects) {
    this.cleanupConfiguredProjects(
      toRetainConfiguredProjects,
      externalProjectsRetainingConfiguredProjects,
      openFilesWithRetainedConfiguredProject
    );
    for (const inferredProject of this.inferredProjects.slice()) {
      if (inferredProject.isOrphan()) {
        this.removeProject(inferredProject);
      }
    }
    this.removeOrphanScriptInfos();
  }
  tryInvokeWildCardDirectories(info) {
    this.configFileExistenceInfoCache.forEach((configFileExistenceInfo, config) => {
      var _a, _b;
      if (!((_a = configFileExistenceInfo.config) == null ? void 0 : _a.parsedCommandLine) || contains(
        configFileExistenceInfo.config.parsedCommandLine.fileNames,
        info.fileName,
        !this.host.useCaseSensitiveFileNames ? equateStringsCaseInsensitive : equateStringsCaseSensitive
      )) {
        return;
      }
      (_b = configFileExistenceInfo.config.watchedDirectories) == null ? void 0 : _b.forEach((watcher, directory) => {
        if (containsPath(directory, info.fileName, !this.host.useCaseSensitiveFileNames)) {
          this.logger.info(`Invoking ${config}:: wildcard for open scriptInfo:: ${info.fileName}`);
          this.onWildCardDirectoryWatcherInvoke(
            directory,
            config,
            configFileExistenceInfo.config,
            watcher.watcher,
            info.fileName
          );
        }
      });
    });
  }
  openClientFileWithNormalizedPath(fileName, fileContent, scriptKind, hasMixedContent, projectRootPath) {
    const existing = this.getScriptInfoForPath(normalizedPathToPath(
      fileName,
      projectRootPath ? this.getNormalizedAbsolutePath(projectRootPath) : this.currentDirectory,
      this.toCanonicalFileName
    ));
    const info = this.getOrCreateOpenScriptInfo(fileName, fileContent, scriptKind, hasMixedContent, projectRootPath);
    if (!existing && info && !info.isDynamic) this.tryInvokeWildCardDirectories(info);
    const { retainProjects, ...result } = this.assignProjectToOpenedScriptInfo(info);
    this.cleanupProjectsAndScriptInfos(
      retainProjects,
      /* @__PURE__ */ new Set([info.path]),
      /*externalProjectsRetainingConfiguredProjects*/
      void 0
    );
    this.telemetryOnOpenFile(info);
    this.printProjects();
    return result;
  }
  /** @internal */
  getOrphanConfiguredProjects(toRetainConfiguredProjects, openFilesWithRetainedConfiguredProject, externalProjectsRetainingConfiguredProjects) {
    const toRemoveConfiguredProjects = new Set(this.configuredProjects.values());
    const markOriginalProjectsAsUsed = (project) => {
      if (project.originalConfiguredProjects && (isConfiguredProject(project) || !project.isOrphan())) {
        project.originalConfiguredProjects.forEach(
          (_value, configuredProjectPath) => {
            const project2 = this.getConfiguredProjectByCanonicalConfigFilePath(configuredProjectPath);
            return project2 && retainConfiguredProject(project2);
          }
        );
      }
    };
    toRetainConfiguredProjects == null ? void 0 : toRetainConfiguredProjects.forEach(retainConfiguredProject);
    this.inferredProjects.forEach(markOriginalProjectsAsUsed);
    this.externalProjects.forEach(markOriginalProjectsAsUsed);
    this.externalProjectToConfiguredProjectMap.forEach((projects, externalProjectName) => {
      if (!(externalProjectsRetainingConfiguredProjects == null ? void 0 : externalProjectsRetainingConfiguredProjects.has(externalProjectName))) {
        projects.forEach(retainConfiguredProject);
      }
    });
    this.openFiles.forEach((_projectRootPath, path) => {
      if (openFilesWithRetainedConfiguredProject == null ? void 0 : openFilesWithRetainedConfiguredProject.has(path)) return;
      const info = this.getScriptInfoForPath(path);
      if (find(info.containingProjects, isExternalProject)) return;
      const result = this.tryFindDefaultConfiguredProjectAndLoadAncestorsForOpenScriptInfo(
        info,
        0 /* Find */
      );
      if (result == null ? void 0 : result.defaultProject) {
        result == null ? void 0 : result.seenProjects.forEach(retainConfiguredProject);
      }
    });
    this.configuredProjects.forEach((project) => {
      if (toRemoveConfiguredProjects.has(project)) {
        if (isPendingUpdate(project) || forEachReferencedProject(project, isRetained)) {
          retainConfiguredProject(project);
        }
      }
    });
    return toRemoveConfiguredProjects;
    function isRetained(project) {
      return !toRemoveConfiguredProjects.has(project) || isPendingUpdate(project);
    }
    function isPendingUpdate(project) {
      var _a, _b;
      return (project.deferredClose || project.projectService.hasPendingProjectUpdate(project)) && !!((_b = (_a = project.projectService.configFileExistenceInfoCache.get(project.canonicalConfigFilePath)) == null ? void 0 : _a.openFilesImpactedByConfigFile) == null ? void 0 : _b.size);
    }
    function retainConfiguredProject(project) {
      if (!toRemoveConfiguredProjects.delete(project)) return;
      markOriginalProjectsAsUsed(project);
      forEachReferencedProject(project, retainConfiguredProject);
    }
  }
  removeOrphanScriptInfos() {
    const toRemoveScriptInfos = new Map(this.filenameToScriptInfo);
    this.filenameToScriptInfo.forEach((info) => {
      if (info.deferredDelete) return;
      if (!info.isScriptOpen() && info.isOrphan() && !info.isContainedByBackgroundProject()) {
        if (!info.sourceMapFilePath) return;
        let sourceInfos;
        if (isString(info.sourceMapFilePath)) {
          const sourceMapInfo = this.filenameToScriptInfo.get(info.sourceMapFilePath);
          sourceInfos = sourceMapInfo == null ? void 0 : sourceMapInfo.sourceInfos;
        } else {
          sourceInfos = info.sourceMapFilePath.sourceInfos;
        }
        if (!sourceInfos) return;
        if (!forEachKey(sourceInfos, (path) => {
          const info2 = this.getScriptInfoForPath(path);
          return !!info2 && (info2.isScriptOpen() || !info2.isOrphan());
        })) {
          return;
        }
      }
      toRemoveScriptInfos.delete(info.path);
      if (info.sourceMapFilePath) {
        let sourceInfos;
        if (isString(info.sourceMapFilePath)) {
          const sourceMapInfo = this.filenameToScriptInfo.get(info.sourceMapFilePath);
          if (sourceMapInfo == null ? void 0 : sourceMapInfo.deferredDelete) {
            info.sourceMapFilePath = {
              watcher: this.addMissingSourceMapFile(sourceMapInfo.fileName, info.path),
              sourceInfos: sourceMapInfo.sourceInfos
            };
          } else {
            toRemoveScriptInfos.delete(info.sourceMapFilePath);
          }
          sourceInfos = sourceMapInfo == null ? void 0 : sourceMapInfo.sourceInfos;
        } else {
          sourceInfos = info.sourceMapFilePath.sourceInfos;
        }
        if (sourceInfos) {
          sourceInfos.forEach((_value, path) => toRemoveScriptInfos.delete(path));
        }
      }
    });
    toRemoveScriptInfos.forEach((info) => this.deleteScriptInfo(info));
  }
  telemetryOnOpenFile(scriptInfo) {
    if (this.serverMode !== 0 /* Semantic */ || !this.eventHandler || !scriptInfo.isJavaScript() || !addToSeen(this.allJsFilesForOpenFileTelemetry, scriptInfo.path)) {
      return;
    }
    const project = this.ensureDefaultProjectForFile(scriptInfo);
    if (!project.languageServiceEnabled) {
      return;
    }
    const sourceFile = project.getSourceFile(scriptInfo.path);
    const checkJs = !!sourceFile && !!sourceFile.checkJsDirective;
    this.eventHandler({ eventName: OpenFileInfoTelemetryEvent, data: { info: { checkJs } } });
  }
  closeClientFile(uncheckedFileName, skipAssignOrphanScriptInfosToInferredProject) {
    const info = this.getScriptInfoForNormalizedPath(toNormalizedPath(uncheckedFileName));
    const result = info ? this.closeOpenFile(info, skipAssignOrphanScriptInfosToInferredProject) : false;
    if (!skipAssignOrphanScriptInfosToInferredProject) {
      this.printProjects();
    }
    return result;
  }
  collectChanges(lastKnownProjectVersions, currentProjects, includeProjectReferenceRedirectInfo, result) {
    for (const proj of currentProjects) {
      const knownProject = find(lastKnownProjectVersions, (p) => p.projectName === proj.getProjectName());
      result.push(proj.getChangesSinceVersion(knownProject && knownProject.version, includeProjectReferenceRedirectInfo));
    }
  }
  /** @internal */
  synchronizeProjectList(knownProjects, includeProjectReferenceRedirectInfo) {
    const files = [];
    this.collectChanges(knownProjects, this.externalProjects, includeProjectReferenceRedirectInfo, files);
    this.collectChanges(knownProjects, mapDefinedIterator(this.configuredProjects.values(), (p) => p.deferredClose ? void 0 : p), includeProjectReferenceRedirectInfo, files);
    this.collectChanges(knownProjects, this.inferredProjects, includeProjectReferenceRedirectInfo, files);
    return files;
  }
  /** @internal */
  applyChangesInOpenFiles(openFiles, changedFiles, closedFiles) {
    let existingOpenScriptInfos;
    let openScriptInfos;
    let assignOrphanScriptInfosToInferredProject = false;
    if (openFiles) {
      for (const file of openFiles) {
        (existingOpenScriptInfos ?? (existingOpenScriptInfos = [])).push(this.getScriptInfoForPath(normalizedPathToPath(
          toNormalizedPath(file.fileName),
          file.projectRootPath ? this.getNormalizedAbsolutePath(file.projectRootPath) : this.currentDirectory,
          this.toCanonicalFileName
        )));
        const info = this.getOrCreateOpenScriptInfo(
          toNormalizedPath(file.fileName),
          file.content,
          tryConvertScriptKindName(file.scriptKind),
          file.hasMixedContent,
          file.projectRootPath ? toNormalizedPath(file.projectRootPath) : void 0
        );
        (openScriptInfos || (openScriptInfos = [])).push(info);
      }
    }
    if (changedFiles) {
      for (const file of changedFiles) {
        const scriptInfo = this.getScriptInfo(file.fileName);
        Debug.assert(!!scriptInfo);
        this.applyChangesToFile(scriptInfo, file.changes);
      }
    }
    if (closedFiles) {
      for (const file of closedFiles) {
        assignOrphanScriptInfosToInferredProject = this.closeClientFile(
          file,
          /*skipAssignOrphanScriptInfosToInferredProject*/
          true
        ) || assignOrphanScriptInfosToInferredProject;
      }
    }
    let retainProjects;
    forEach(
      existingOpenScriptInfos,
      (existing, index) => !existing && openScriptInfos[index] && !openScriptInfos[index].isDynamic ? this.tryInvokeWildCardDirectories(openScriptInfos[index]) : void 0
    );
    openScriptInfos == null ? void 0 : openScriptInfos.forEach((info) => {
      var _a;
      return (_a = this.assignProjectToOpenedScriptInfo(info).retainProjects) == null ? void 0 : _a.forEach((p) => (retainProjects ?? (retainProjects = /* @__PURE__ */ new Set())).add(p));
    });
    if (assignOrphanScriptInfosToInferredProject) {
      this.assignOrphanScriptInfosToInferredProject();
    }
    if (openScriptInfos) {
      this.cleanupProjectsAndScriptInfos(
        retainProjects,
        new Set(openScriptInfos.map((info) => info.path)),
        /*externalProjectsRetainingConfiguredProjects*/
        void 0
      );
      openScriptInfos.forEach((info) => this.telemetryOnOpenFile(info));
      this.printProjects();
    } else if (length(closedFiles)) {
      this.printProjects();
    }
  }
  /** @internal */
  applyChangesToFile(scriptInfo, changes) {
    for (const change of changes) {
      scriptInfo.editContent(change.span.start, change.span.start + change.span.length, change.newText);
    }
  }
  // eslint-disable-line @typescript-eslint/unified-signatures
  closeExternalProject(uncheckedFileName, cleanupAfter) {
    const fileName = toNormalizedPath(uncheckedFileName);
    const projects = this.externalProjectToConfiguredProjectMap.get(fileName);
    if (projects) {
      this.externalProjectToConfiguredProjectMap.delete(fileName);
    } else {
      const externalProject = this.findExternalProjectByProjectName(uncheckedFileName);
      if (externalProject) {
        this.removeProject(externalProject);
      }
    }
    if (cleanupAfter) {
      this.cleanupConfiguredProjects();
      this.printProjects();
    }
  }
  openExternalProjects(projects) {
    const projectsToClose = new Set(this.externalProjects.map((p) => p.getProjectName()));
    this.externalProjectToConfiguredProjectMap.forEach((_, externalProjectName) => projectsToClose.add(externalProjectName));
    for (const externalProject of projects) {
      this.openExternalProject(
        externalProject,
        /*cleanupAfter*/
        false
      );
      projectsToClose.delete(externalProject.projectFileName);
    }
    projectsToClose.forEach((externalProjectName) => this.closeExternalProject(
      externalProjectName,
      /*cleanupAfter*/
      false
    ));
    this.cleanupConfiguredProjects();
    this.printProjects();
  }
  static escapeFilenameForRegex(filename) {
    return filename.replace(this.filenameEscapeRegexp, "\\$&");
  }
  resetSafeList() {
    this.safelist = defaultTypeSafeList;
  }
  applySafeList(proj) {
    const typeAcquisition = proj.typeAcquisition;
    Debug.assert(!!typeAcquisition, "proj.typeAcquisition should be set by now");
    const result = this.applySafeListWorker(proj, proj.rootFiles, typeAcquisition);
    return (result == null ? void 0 : result.excludedFiles) ?? [];
  }
  applySafeListWorker(proj, rootFiles, typeAcquisition) {
    if (typeAcquisition.enable === false || typeAcquisition.disableFilenameBasedTypeAcquisition) {
      return void 0;
    }
    const typeAcqInclude = typeAcquisition.include || (typeAcquisition.include = []);
    const excludeRules = [];
    const normalizedNames = rootFiles.map((f) => normalizeSlashes(f.fileName));
    for (const name of Object.keys(this.safelist)) {
      const rule2 = this.safelist[name];
      for (const root of normalizedNames) {
        if (rule2.match.test(root)) {
          this.logger.info(`Excluding files based on rule ${name} matching file '${root}'`);
          if (rule2.types) {
            for (const type of rule2.types) {
              if (!typeAcqInclude.includes(type)) {
                typeAcqInclude.push(type);
              }
            }
          }
          if (rule2.exclude) {
            for (const exclude of rule2.exclude) {
              const processedRule = root.replace(rule2.match, (...groups) => {
                return exclude.map((groupNumberOrString) => {
                  if (typeof groupNumberOrString === "number") {
                    if (!isString(groups[groupNumberOrString])) {
                      this.logger.info(`Incorrect RegExp specification in safelist rule ${name} - not enough groups`);
                      return "\\*";
                    }
                    return _ProjectService.escapeFilenameForRegex(groups[groupNumberOrString]);
                  }
                  return groupNumberOrString;
                }).join("");
              });
              if (!excludeRules.includes(processedRule)) {
                excludeRules.push(processedRule);
              }
            }
          } else {
            const escaped = _ProjectService.escapeFilenameForRegex(root);
            if (!excludeRules.includes(escaped)) {
              excludeRules.push(escaped);
            }
          }
        }
      }
    }
    const excludeRegexes = excludeRules.map((e) => new RegExp(e, "i"));
    let filesToKeep;
    let excludedFiles;
    for (let i = 0; i < rootFiles.length; i++) {
      if (excludeRegexes.some((re) => re.test(normalizedNames[i]))) {
        addExcludedFile(i);
      } else {
        if (typeAcquisition.enable) {
          const baseName = getBaseFileName(toFileNameLowerCase(normalizedNames[i]));
          if (fileExtensionIs(baseName, "js")) {
            const inferredTypingName = removeFileExtension(baseName);
            const cleanedTypingName = removeMinAndVersionNumbers(inferredTypingName);
            const typeName = this.legacySafelist.get(cleanedTypingName);
            if (typeName !== void 0) {
              this.logger.info(`Excluded '${normalizedNames[i]}' because it matched ${cleanedTypingName} from the legacy safelist`);
              addExcludedFile(i);
              if (!typeAcqInclude.includes(typeName)) {
                typeAcqInclude.push(typeName);
              }
              continue;
            }
          }
        }
        if (/^.+[.-]min\.js$/.test(normalizedNames[i])) {
          addExcludedFile(i);
        } else {
          filesToKeep == null ? void 0 : filesToKeep.push(rootFiles[i]);
        }
      }
    }
    return excludedFiles ? {
      rootFiles: filesToKeep,
      excludedFiles
    } : void 0;
    function addExcludedFile(index) {
      if (!excludedFiles) {
        Debug.assert(!filesToKeep);
        filesToKeep = rootFiles.slice(0, index);
        excludedFiles = [];
      }
      excludedFiles.push(normalizedNames[index]);
    }
  }
  // eslint-disable-line @typescript-eslint/unified-signatures
  openExternalProject(proj, cleanupAfter) {
    const existingExternalProject = this.findExternalProjectByProjectName(proj.projectFileName);
    let configuredProjects;
    let rootFiles = [];
    for (const file of proj.rootFiles) {
      const normalized = toNormalizedPath(file.fileName);
      if (getBaseConfigFileName(normalized)) {
        if (this.serverMode === 0 /* Semantic */ && this.host.fileExists(normalized)) {
          let project = this.findConfiguredProjectByProjectName(normalized);
          if (!project) {
            project = this.createConfiguredProject(normalized, `Creating configured project in external project: ${proj.projectFileName}`);
            if (!this.getHostPreferences().lazyConfiguredProjectsFromExternalProject) project.updateGraph();
          }
          (configuredProjects ?? (configuredProjects = /* @__PURE__ */ new Set())).add(project);
          Debug.assert(!project.isClosed());
        }
      } else {
        rootFiles.push(file);
      }
    }
    if (configuredProjects) {
      this.externalProjectToConfiguredProjectMap.set(proj.projectFileName, configuredProjects);
      if (existingExternalProject) this.removeProject(existingExternalProject);
    } else {
      this.externalProjectToConfiguredProjectMap.delete(proj.projectFileName);
      const typeAcquisition = proj.typeAcquisition || {};
      typeAcquisition.include = typeAcquisition.include || [];
      typeAcquisition.exclude = typeAcquisition.exclude || [];
      if (typeAcquisition.enable === void 0) {
        typeAcquisition.enable = hasNoTypeScriptSource(rootFiles.map((f) => f.fileName));
      }
      const excludeResult = this.applySafeListWorker(proj, rootFiles, typeAcquisition);
      const excludedFiles = (excludeResult == null ? void 0 : excludeResult.excludedFiles) ?? [];
      rootFiles = (excludeResult == null ? void 0 : excludeResult.rootFiles) ?? rootFiles;
      if (existingExternalProject) {
        existingExternalProject.excludedFiles = excludedFiles;
        const compilerOptions = convertCompilerOptions(proj.options);
        const watchOptionsAndErrors = convertWatchOptions(proj.options, existingExternalProject.getCurrentDirectory());
        const lastFileExceededProgramSize = this.getFilenameForExceededTotalSizeLimitForNonTsFiles(proj.projectFileName, compilerOptions, rootFiles, externalFilePropertyReader);
        if (lastFileExceededProgramSize) {
          existingExternalProject.disableLanguageService(lastFileExceededProgramSize);
        } else {
          existingExternalProject.enableLanguageService();
        }
        existingExternalProject.setProjectErrors(watchOptionsAndErrors == null ? void 0 : watchOptionsAndErrors.errors);
        this.updateRootAndOptionsOfNonInferredProject(existingExternalProject, rootFiles, externalFilePropertyReader, compilerOptions, typeAcquisition, proj.options.compileOnSave, watchOptionsAndErrors == null ? void 0 : watchOptionsAndErrors.watchOptions);
        existingExternalProject.updateGraph();
      } else {
        const project = this.createExternalProject(proj.projectFileName, rootFiles, proj.options, typeAcquisition, excludedFiles);
        project.updateGraph();
      }
    }
    if (cleanupAfter) {
      this.cleanupConfiguredProjects(
        configuredProjects,
        new Set(proj.projectFileName)
      );
      this.printProjects();
    }
  }
  hasDeferredExtension() {
    for (const extension of this.hostConfiguration.extraFileExtensions) {
      if (extension.scriptKind === 7 /* Deferred */) {
        return true;
      }
    }
    return false;
  }
  /**
   * Performs the initial steps of enabling a plugin by finding and instantiating the module for a plugin either asynchronously or synchronously
   * @internal
   */
  requestEnablePlugin(project, pluginConfigEntry, searchPaths) {
    if (!this.host.importPlugin && !this.host.require) {
      this.logger.info("Plugins were requested but not running in environment that supports 'require'. Nothing will be loaded");
      return;
    }
    this.logger.info(`Enabling plugin ${pluginConfigEntry.name} from candidate paths: ${searchPaths.join(",")}`);
    if (!pluginConfigEntry.name || isExternalModuleNameRelative(pluginConfigEntry.name) || /[\\/]\.\.?(?:$|[\\/])/.test(pluginConfigEntry.name)) {
      this.logger.info(`Skipped loading plugin ${pluginConfigEntry.name || JSON.stringify(pluginConfigEntry)} because only package name is allowed plugin name`);
      return;
    }
    if (this.host.importPlugin) {
      const importPromise = Project2.importServicePluginAsync(
        pluginConfigEntry,
        searchPaths,
        this.host,
        (s) => this.logger.info(s)
      );
      this.pendingPluginEnablements ?? (this.pendingPluginEnablements = /* @__PURE__ */ new Map());
      let promises = this.pendingPluginEnablements.get(project);
      if (!promises) this.pendingPluginEnablements.set(project, promises = []);
      promises.push(importPromise);
      return;
    }
    this.endEnablePlugin(
      project,
      Project2.importServicePluginSync(
        pluginConfigEntry,
        searchPaths,
        this.host,
        (s) => this.logger.info(s)
      )
    );
  }
  /**
   * Performs the remaining steps of enabling a plugin after its module has been instantiated.
   */
  endEnablePlugin(project, { pluginConfigEntry, resolvedModule, errorLogs }) {
    var _a;
    if (resolvedModule) {
      const configurationOverride = (_a = this.currentPluginConfigOverrides) == null ? void 0 : _a.get(pluginConfigEntry.name);
      if (configurationOverride) {
        const pluginName = pluginConfigEntry.name;
        pluginConfigEntry = configurationOverride;
        pluginConfigEntry.name = pluginName;
      }
      project.enableProxy(resolvedModule, pluginConfigEntry);
    } else {
      forEach(errorLogs, (message) => this.logger.info(message));
      this.logger.info(`Couldn't find ${pluginConfigEntry.name}`);
    }
  }
  /** @internal */
  hasNewPluginEnablementRequests() {
    return !!this.pendingPluginEnablements;
  }
  /** @internal */
  hasPendingPluginEnablements() {
    return !!this.currentPluginEnablementPromise;
  }
  /**
   * Waits for any ongoing plugin enablement requests to complete.
   *
   * @internal
   */
  async waitForPendingPlugins() {
    while (this.currentPluginEnablementPromise) {
      await this.currentPluginEnablementPromise;
    }
  }
  /**
   * Starts enabling any requested plugins without waiting for the result.
   *
   * @internal
   */
  enableRequestedPlugins() {
    if (this.pendingPluginEnablements) {
      void this.enableRequestedPluginsAsync();
    }
  }
  async enableRequestedPluginsAsync() {
    if (this.currentPluginEnablementPromise) {
      await this.waitForPendingPlugins();
    }
    if (!this.pendingPluginEnablements) {
      return;
    }
    const entries = arrayFrom(this.pendingPluginEnablements.entries());
    this.pendingPluginEnablements = void 0;
    this.currentPluginEnablementPromise = this.enableRequestedPluginsWorker(entries);
    await this.currentPluginEnablementPromise;
  }
  async enableRequestedPluginsWorker(pendingPlugins) {
    Debug.assert(this.currentPluginEnablementPromise === void 0);
    let sendProjectsUpdatedInBackgroundEvent = false;
    await Promise.all(map(pendingPlugins, async ([project, promises]) => {
      const results = await Promise.all(promises);
      if (project.isClosed() || isProjectDeferredClose(project)) {
        this.logger.info(`Cancelling plugin enabling for ${project.getProjectName()} as it is ${project.isClosed() ? "closed" : "deferred close"}`);
        return;
      }
      sendProjectsUpdatedInBackgroundEvent = true;
      for (const result of results) {
        this.endEnablePlugin(project, result);
      }
      this.delayUpdateProjectGraph(project);
    }));
    this.currentPluginEnablementPromise = void 0;
    if (sendProjectsUpdatedInBackgroundEvent) this.sendProjectsUpdatedInBackgroundEvent();
  }
  configurePlugin(args) {
    this.forEachEnabledProject((project) => project.onPluginConfigurationChanged(args.pluginName, args.configuration));
    this.currentPluginConfigOverrides = this.currentPluginConfigOverrides || /* @__PURE__ */ new Map();
    this.currentPluginConfigOverrides.set(args.pluginName, args.configuration);
  }
  /** @internal */
  getPackageJsonsVisibleToFile(fileName, project, rootDir) {
    const packageJsonCache = this.packageJsonCache;
    const rootPath = rootDir && this.toPath(rootDir);
    const result = [];
    const processDirectory = (directory) => {
      switch (packageJsonCache.directoryHasPackageJson(directory)) {
        case 3 /* Maybe */:
          packageJsonCache.searchDirectoryAndAncestors(directory);
          return processDirectory(directory);
        case -1 /* True */:
          const packageJsonFileName = combinePaths(directory, "package.json");
          this.watchPackageJsonFile(packageJsonFileName, this.toPath(packageJsonFileName), project);
          const info = packageJsonCache.getInDirectory(directory);
          if (info) result.push(info);
      }
      if (rootPath && rootPath === directory) {
        return true;
      }
    };
    forEachAncestorDirectory(getDirectoryPath(fileName), processDirectory);
    return result;
  }
  /** @internal */
  getNearestAncestorDirectoryWithPackageJson(fileName) {
    return forEachAncestorDirectory(fileName, (directory) => {
      switch (this.packageJsonCache.directoryHasPackageJson(directory)) {
        case -1 /* True */:
          return directory;
        case 0 /* False */:
          return void 0;
        case 3 /* Maybe */:
          return this.host.fileExists(combinePaths(directory, "package.json")) ? directory : void 0;
      }
    });
  }
  watchPnpFile() {
    const pnpApiPath = getPnpApiPath(__filename);
    if (!pnpApiPath) {
      return;
    }
    return this.watchFactory.watchFile(
      pnpApiPath,
      () => {
        this.forEachProject((project) => {
          for (const info of project.getScriptInfos()) {
            project.resolutionCache.invalidateResolutionOfFile(info.path);
          }
          project.markAsDirty();
          updateProjectIfDirty(project);
        });
        this.delayEnsureProjectForOpenFiles();
      },
      250 /* Low */,
      this.hostConfiguration.watchOptions,
      WatchType.ConfigFile
    );
  }
  watchPackageJsonFile(file, path, project) {
    Debug.assert(project !== void 0);
    let result = (this.packageJsonFilesMap ?? (this.packageJsonFilesMap = /* @__PURE__ */ new Map())).get(path);
    if (!result) {
      let watcher = this.watchFactory.watchFile(
        file,
        (fileName, eventKind) => {
          switch (eventKind) {
            case 0 /* Created */:
            case 1 /* Changed */:
              this.packageJsonCache.addOrUpdate(fileName, path);
              this.onPackageJsonChange(result);
              break;
            case 2 /* Deleted */:
              this.packageJsonCache.delete(path);
              this.onPackageJsonChange(result);
              result.projects.clear();
              result.close();
          }
        },
        250 /* Low */,
        this.hostConfiguration.watchOptions,
        WatchType.PackageJson
      );
      result = {
        projects: /* @__PURE__ */ new Set(),
        close: () => {
          var _a;
          if (result.projects.size || !watcher) return;
          watcher.close();
          watcher = void 0;
          (_a = this.packageJsonFilesMap) == null ? void 0 : _a.delete(path);
          this.packageJsonCache.invalidate(path);
        }
      };
      this.packageJsonFilesMap.set(path, result);
    }
    result.projects.add(project);
    (project.packageJsonWatches ?? (project.packageJsonWatches = /* @__PURE__ */ new Set())).add(result);
  }
  onPackageJsonChange(result) {
    result.projects.forEach((project) => {
      var _a;
      return (_a = project.onPackageJsonChange) == null ? void 0 : _a.call(project);
    });
  }
  /** @internal */
  includePackageJsonAutoImports() {
    switch (this.hostConfiguration.preferences.includePackageJsonAutoImports) {
      case "on":
        return 1 /* On */;
      case "off":
        return 0 /* Off */;
      default:
        return 2 /* Auto */;
    }
  }
  /** @internal */
  getIncompleteCompletionsCache() {
    return this.incompleteCompletionsCache || (this.incompleteCompletionsCache = createIncompleteCompletionsCache());
  }
};
/** Makes a filename safe to insert in a RegExp */
_ProjectService.filenameEscapeRegexp = /[-/\\^$*+?.()|[\]{}]/g;
var ProjectService2 = _ProjectService;
function createIncompleteCompletionsCache() {
  let info;
  return {
    get() {
      return info;
    },
    set(newInfo) {
      info = newInfo;
    },
    clear() {
      info = void 0;
    }
  };
}
function isConfigFile(config) {
  return config.kind !== void 0;
}
function printProjectWithoutFileNames(project) {
  project.print(
    /*writeProjectFileNames*/
    false,
    /*writeFileExplaination*/
    false,
    /*writeFileVersionAndText*/
    false
  );
}

// src/server/moduleSpecifierCache.ts
function createModuleSpecifierCache(host) {
  let containedNodeModulesWatchers;
  let cache;
  let currentKey;
  const result = {
    get(fromFileName, toFileName2, preferences, options) {
      if (!cache || currentKey !== key(fromFileName, preferences, options)) return void 0;
      return cache.get(toFileName2);
    },
    set(fromFileName, toFileName2, preferences, options, kind, modulePaths, moduleSpecifiers) {
      ensureCache(fromFileName, preferences, options).set(toFileName2, createInfo(
        kind,
        modulePaths,
        moduleSpecifiers,
        /*packageName*/
        void 0,
        /*isBlockedByPackageJsonDependencies*/
        false
      ));
      if (moduleSpecifiers) {
        for (const p of modulePaths) {
          if (p.isInNodeModules) {
            const nodeModulesPath = p.path.substring(0, p.path.indexOf(nodeModulesPathPart) + nodeModulesPathPart.length - 1);
            const key2 = host.toPath(nodeModulesPath);
            if (!(containedNodeModulesWatchers == null ? void 0 : containedNodeModulesWatchers.has(key2))) {
              (containedNodeModulesWatchers || (containedNodeModulesWatchers = /* @__PURE__ */ new Map())).set(
                key2,
                host.watchNodeModulesForPackageJsonChanges(nodeModulesPath)
              );
            }
          }
        }
      }
    },
    setModulePaths(fromFileName, toFileName2, preferences, options, modulePaths) {
      const cache2 = ensureCache(fromFileName, preferences, options);
      const info = cache2.get(toFileName2);
      if (info) {
        info.modulePaths = modulePaths;
      } else {
        cache2.set(toFileName2, createInfo(
          /*kind*/
          void 0,
          modulePaths,
          /*moduleSpecifiers*/
          void 0,
          /*packageName*/
          void 0,
          /*isBlockedByPackageJsonDependencies*/
          void 0
        ));
      }
    },
    setBlockedByPackageJsonDependencies(fromFileName, toFileName2, preferences, options, packageName, isBlockedByPackageJsonDependencies) {
      const cache2 = ensureCache(fromFileName, preferences, options);
      const info = cache2.get(toFileName2);
      if (info) {
        info.isBlockedByPackageJsonDependencies = isBlockedByPackageJsonDependencies;
        info.packageName = packageName;
      } else {
        cache2.set(toFileName2, createInfo(
          /*kind*/
          void 0,
          /*modulePaths*/
          void 0,
          /*moduleSpecifiers*/
          void 0,
          packageName,
          isBlockedByPackageJsonDependencies
        ));
      }
    },
    clear() {
      containedNodeModulesWatchers == null ? void 0 : containedNodeModulesWatchers.forEach(closeFileWatcher);
      cache == null ? void 0 : cache.clear();
      containedNodeModulesWatchers == null ? void 0 : containedNodeModulesWatchers.clear();
      currentKey = void 0;
    },
    count() {
      return cache ? cache.size : 0;
    }
  };
  if (Debug.isDebugging) {
    Object.defineProperty(result, "__cache", { get: () => cache });
  }
  return result;
  function ensureCache(fromFileName, preferences, options) {
    const newKey = key(fromFileName, preferences, options);
    if (cache && currentKey !== newKey) {
      result.clear();
    }
    currentKey = newKey;
    return cache || (cache = /* @__PURE__ */ new Map());
  }
  function key(fromFileName, preferences, options) {
    return `${fromFileName},${preferences.importModuleSpecifierEnding},${preferences.importModuleSpecifierPreference},${options.overrideImportMode}`;
  }
  function createInfo(kind, modulePaths, moduleSpecifiers, packageName, isBlockedByPackageJsonDependencies) {
    return { kind, modulePaths, moduleSpecifiers, packageName, isBlockedByPackageJsonDependencies };
  }
}

// src/server/packageJsonCache.ts
function createPackageJsonCache(host) {
  const packageJsons = /* @__PURE__ */ new Map();
  const directoriesWithoutPackageJson = /* @__PURE__ */ new Map();
  return {
    addOrUpdate,
    invalidate,
    delete: (fileName) => {
      packageJsons.delete(fileName);
      directoriesWithoutPackageJson.set(getDirectoryPath(fileName), true);
    },
    getInDirectory: (directory) => {
      return packageJsons.get(host.toPath(combinePaths(directory, "package.json"))) || void 0;
    },
    directoryHasPackageJson: (directory) => directoryHasPackageJson(host.toPath(directory)),
    searchDirectoryAndAncestors: (directory) => {
      forEachAncestorDirectory(directory, (ancestor) => {
        const ancestorPath = host.toPath(ancestor);
        if (directoryHasPackageJson(ancestorPath) !== 3 /* Maybe */) {
          return true;
        }
        const packageJsonFileName = combinePaths(ancestor, "package.json");
        if (tryFileExists(host, packageJsonFileName)) {
          addOrUpdate(packageJsonFileName, combinePaths(ancestorPath, "package.json"));
        } else {
          directoriesWithoutPackageJson.set(ancestorPath, true);
        }
      });
    }
  };
  function addOrUpdate(fileName, path) {
    const packageJsonInfo = Debug.checkDefined(createPackageJsonInfo(fileName, host.host));
    packageJsons.set(path, packageJsonInfo);
    directoriesWithoutPackageJson.delete(getDirectoryPath(path));
  }
  function invalidate(path) {
    packageJsons.delete(path);
    directoriesWithoutPackageJson.delete(getDirectoryPath(path));
  }
  function directoryHasPackageJson(directory) {
    return packageJsons.has(combinePaths(directory, "package.json")) ? -1 /* True */ : directoriesWithoutPackageJson.has(directory) ? 0 /* False */ : 3 /* Maybe */;
  }
}

// src/server/session.ts
var nullCancellationToken = {
  isCancellationRequested: () => false,
  setRequest: () => void 0,
  resetRequest: () => void 0
};
function hrTimeToMilliseconds(time) {
  const seconds = time[0];
  const nanoseconds = time[1];
  return (1e9 * seconds + nanoseconds) / 1e6;
}
function isDeclarationFileInJSOnlyNonConfiguredProject(project, file) {
  if ((isInferredProject(project) || isExternalProject(project)) && project.isJsOnlyProject()) {
    const scriptInfo = project.getScriptInfoForNormalizedPath(file);
    return scriptInfo && !scriptInfo.isJavaScript();
  }
  return false;
}
function dtsChangeCanAffectEmit(compilationSettings) {
  return getEmitDeclarations(compilationSettings) || !!compilationSettings.emitDecoratorMetadata;
}
function formatDiag(fileName, project, diag2) {
  const scriptInfo = project.getScriptInfoForNormalizedPath(fileName);
  return {
    start: scriptInfo.positionToLineOffset(diag2.start),
    end: scriptInfo.positionToLineOffset(diag2.start + diag2.length),
    // TODO: GH#18217
    text: flattenDiagnosticMessageText(diag2.messageText, "\n"),
    code: diag2.code,
    category: diagnosticCategoryName(diag2),
    reportsUnnecessary: diag2.reportsUnnecessary,
    reportsDeprecated: diag2.reportsDeprecated,
    source: diag2.source,
    relatedInformation: map(diag2.relatedInformation, formatRelatedInformation)
  };
}
function formatRelatedInformation(info) {
  if (!info.file) {
    return {
      message: flattenDiagnosticMessageText(info.messageText, "\n"),
      category: diagnosticCategoryName(info),
      code: info.code
    };
  }
  return {
    span: {
      start: convertToLocation(getLineAndCharacterOfPosition(info.file, info.start)),
      end: convertToLocation(getLineAndCharacterOfPosition(info.file, info.start + info.length)),
      // TODO: GH#18217
      file: info.file.fileName
    },
    message: flattenDiagnosticMessageText(info.messageText, "\n"),
    category: diagnosticCategoryName(info),
    code: info.code
  };
}
function convertToLocation(lineAndCharacter) {
  return { line: lineAndCharacter.line + 1, offset: lineAndCharacter.character + 1 };
}
function formatDiagnosticToProtocol(diag2, includeFileName) {
  const start = diag2.file && convertToLocation(getLineAndCharacterOfPosition(diag2.file, diag2.start));
  const end = diag2.file && convertToLocation(getLineAndCharacterOfPosition(diag2.file, diag2.start + diag2.length));
  const text = flattenDiagnosticMessageText(diag2.messageText, "\n");
  const { code, source } = diag2;
  const category = diagnosticCategoryName(diag2);
  const common = {
    start,
    end,
    text,
    code,
    category,
    reportsUnnecessary: diag2.reportsUnnecessary,
    reportsDeprecated: diag2.reportsDeprecated,
    source,
    relatedInformation: map(diag2.relatedInformation, formatRelatedInformation)
  };
  return includeFileName ? { ...common, fileName: diag2.file && diag2.file.fileName } : common;
}
function allEditsBeforePos(edits, pos) {
  return edits.every((edit) => textSpanEnd(edit.span) < pos);
}
var CommandNames = CommandTypes;
function formatMessage2(msg, logger, byteLength, newLine) {
  const verboseLogging = logger.hasLevel(3 /* verbose */);
  const json = JSON.stringify(msg);
  if (verboseLogging) {
    logger.info(`${msg.type}:${stringifyIndented(msg)}`);
  }
  const len = byteLength(json, "utf8");
  return `Content-Length: ${1 + len}\r
\r
${json}${newLine}`;
}
var MultistepOperation = class {
  constructor(operationHost) {
    this.operationHost = operationHost;
  }
  startNew(action) {
    this.complete();
    this.requestId = this.operationHost.getCurrentRequestId();
    this.executeAction(action);
  }
  complete() {
    if (this.requestId !== void 0) {
      this.operationHost.sendRequestCompletedEvent(this.requestId, this.performanceData);
      this.requestId = void 0;
    }
    this.setTimerHandle(void 0);
    this.setImmediateId(void 0);
    this.performanceData = void 0;
  }
  immediate(actionType, action) {
    const requestId = this.requestId;
    Debug.assert(requestId === this.operationHost.getCurrentRequestId(), "immediate: incorrect request id");
    this.setImmediateId(
      this.operationHost.getServerHost().setImmediate(() => {
        this.immediateId = void 0;
        this.operationHost.executeWithRequestId(requestId, () => this.executeAction(action), this.performanceData);
      }, actionType)
    );
  }
  delay(actionType, ms, action) {
    const requestId = this.requestId;
    Debug.assert(requestId === this.operationHost.getCurrentRequestId(), "delay: incorrect request id");
    this.setTimerHandle(
      this.operationHost.getServerHost().setTimeout(
        () => {
          this.timerHandle = void 0;
          this.operationHost.executeWithRequestId(requestId, () => this.executeAction(action), this.performanceData);
        },
        ms,
        actionType
      )
    );
  }
  executeAction(action) {
    var _a, _b, _c, _d, _e, _f;
    let stop = false;
    try {
      if (this.operationHost.isCancellationRequested()) {
        stop = true;
        (_a = tracing) == null ? void 0 : _a.instant(tracing.Phase.Session, "stepCanceled", { seq: this.requestId, early: true });
      } else {
        (_b = tracing) == null ? void 0 : _b.push(tracing.Phase.Session, "stepAction", { seq: this.requestId });
        action(this);
        (_c = tracing) == null ? void 0 : _c.pop();
      }
    } catch (e) {
      (_d = tracing) == null ? void 0 : _d.popAll();
      stop = true;
      if (e instanceof OperationCanceledException) {
        (_e = tracing) == null ? void 0 : _e.instant(tracing.Phase.Session, "stepCanceled", { seq: this.requestId });
      } else {
        (_f = tracing) == null ? void 0 : _f.instant(tracing.Phase.Session, "stepError", { seq: this.requestId, message: e.message });
        this.operationHost.logError(e, `delayed processing of request ${this.requestId}`);
      }
    }
    this.performanceData = this.operationHost.getPerformanceData();
    if (stop || !this.hasPendingWork()) {
      this.complete();
    }
  }
  setTimerHandle(timerHandle) {
    if (this.timerHandle !== void 0) {
      this.operationHost.getServerHost().clearTimeout(this.timerHandle);
    }
    this.timerHandle = timerHandle;
  }
  setImmediateId(immediateId) {
    if (this.immediateId !== void 0) {
      this.operationHost.getServerHost().clearImmediate(this.immediateId);
    }
    this.immediateId = immediateId;
  }
  hasPendingWork() {
    return !!this.timerHandle || !!this.immediateId;
  }
};
function toEvent(eventName, body) {
  return {
    seq: 0,
    type: "event",
    event: eventName,
    body
  };
}
function combineProjectOutput(defaultValue, getValue, projects, action) {
  const outputs = flatMapToMutable(isArray(projects) ? projects : projects.projects, (project) => action(project, defaultValue));
  if (!isArray(projects) && projects.symLinkedProjects) {
    projects.symLinkedProjects.forEach((projects2, path) => {
      const value = getValue(path);
      outputs.push(...flatMap(projects2, (project) => action(project, value)));
    });
  }
  return deduplicate(outputs, equateValues);
}
function createDocumentSpanSet(useCaseSensitiveFileNames2) {
  return createSet(({ textSpan }) => textSpan.start + 100003 * textSpan.length, getDocumentSpansEqualityComparer(useCaseSensitiveFileNames2));
}
function getRenameLocationsWorker(projects, defaultProject, initialLocation, findInStrings, findInComments, preferences, useCaseSensitiveFileNames2) {
  const perProjectResults = getPerProjectReferences(
    projects,
    defaultProject,
    initialLocation,
    /*isForRename*/
    true,
    (project, position) => project.getLanguageService().findRenameLocations(position.fileName, position.pos, findInStrings, findInComments, preferences),
    (renameLocation, cb) => cb(documentSpanLocation(renameLocation))
  );
  if (isArray(perProjectResults)) {
    return perProjectResults;
  }
  const results = [];
  const seen = createDocumentSpanSet(useCaseSensitiveFileNames2);
  perProjectResults.forEach((projectResults, project) => {
    for (const result of projectResults) {
      if (!seen.has(result) && !getMappedLocationForProject(documentSpanLocation(result), project)) {
        results.push(result);
        seen.add(result);
      }
    }
  });
  return results;
}
function getDefinitionLocation(defaultProject, initialLocation, isForRename) {
  const infos = defaultProject.getLanguageService().getDefinitionAtPosition(
    initialLocation.fileName,
    initialLocation.pos,
    /*searchOtherFilesOnly*/
    false,
    /*stopAtAlias*/
    isForRename
  );
  const info = infos && firstOrUndefined(infos);
  return info && !info.isLocal ? { fileName: info.fileName, pos: info.textSpan.start } : void 0;
}
function getReferencesWorker(projects, defaultProject, initialLocation, useCaseSensitiveFileNames2, logger) {
  var _a, _b;
  const perProjectResults = getPerProjectReferences(
    projects,
    defaultProject,
    initialLocation,
    /*isForRename*/
    false,
    (project, position) => {
      logger.info(`Finding references to ${position.fileName} position ${position.pos} in project ${project.getProjectName()}`);
      return project.getLanguageService().findReferences(position.fileName, position.pos);
    },
    (referencedSymbol, cb) => {
      cb(documentSpanLocation(referencedSymbol.definition));
      for (const ref of referencedSymbol.references) {
        cb(documentSpanLocation(ref));
      }
    }
  );
  if (isArray(perProjectResults)) {
    return perProjectResults;
  }
  const defaultProjectResults = perProjectResults.get(defaultProject);
  if (((_b = (_a = defaultProjectResults == null ? void 0 : defaultProjectResults[0]) == null ? void 0 : _a.references[0]) == null ? void 0 : _b.isDefinition) === void 0) {
    perProjectResults.forEach((projectResults) => {
      for (const referencedSymbol of projectResults) {
        for (const ref of referencedSymbol.references) {
          delete ref.isDefinition;
        }
      }
    });
  } else {
    const knownSymbolSpans = createDocumentSpanSet(useCaseSensitiveFileNames2);
    for (const referencedSymbol of defaultProjectResults) {
      for (const ref of referencedSymbol.references) {
        if (ref.isDefinition) {
          knownSymbolSpans.add(ref);
          break;
        }
      }
    }
    const updatedProjects = /* @__PURE__ */ new Set();
    while (true) {
      let progress = false;
      perProjectResults.forEach((referencedSymbols, project) => {
        if (updatedProjects.has(project)) return;
        const updated = project.getLanguageService().updateIsDefinitionOfReferencedSymbols(referencedSymbols, knownSymbolSpans);
        if (updated) {
          updatedProjects.add(project);
          progress = true;
        }
      });
      if (!progress) break;
    }
    perProjectResults.forEach((referencedSymbols, project) => {
      if (updatedProjects.has(project)) return;
      for (const referencedSymbol of referencedSymbols) {
        for (const ref of referencedSymbol.references) {
          ref.isDefinition = false;
        }
      }
    });
  }
  const results = [];
  const seenRefs = createDocumentSpanSet(useCaseSensitiveFileNames2);
  perProjectResults.forEach((projectResults, project) => {
    for (const referencedSymbol of projectResults) {
      const mappedDefinitionFile = getMappedLocationForProject(documentSpanLocation(referencedSymbol.definition), project);
      const definition = mappedDefinitionFile === void 0 ? referencedSymbol.definition : {
        ...referencedSymbol.definition,
        textSpan: createTextSpan(mappedDefinitionFile.pos, referencedSymbol.definition.textSpan.length),
        // Why would the length be the same in the original?
        fileName: mappedDefinitionFile.fileName,
        contextSpan: getMappedContextSpanForProject(referencedSymbol.definition, project)
      };
      let symbolToAddTo = find(results, (o) => documentSpansEqual(o.definition, definition, useCaseSensitiveFileNames2));
      if (!symbolToAddTo) {
        symbolToAddTo = { definition, references: [] };
        results.push(symbolToAddTo);
      }
      for (const ref of referencedSymbol.references) {
        if (!seenRefs.has(ref) && !getMappedLocationForProject(documentSpanLocation(ref), project)) {
          seenRefs.add(ref);
          symbolToAddTo.references.push(ref);
        }
      }
    }
  });
  return results.filter((o) => o.references.length !== 0);
}
function forEachProjectInProjects(projects, path, cb) {
  for (const project of isArray(projects) ? projects : projects.projects) {
    cb(project, path);
  }
  if (!isArray(projects) && projects.symLinkedProjects) {
    projects.symLinkedProjects.forEach((symlinkedProjects, symlinkedPath) => {
      for (const project of symlinkedProjects) {
        cb(project, symlinkedPath);
      }
    });
  }
}
function getPerProjectReferences(projects, defaultProject, initialLocation, isForRename, getResultsForPosition, forPositionInResult) {
  const resultsMap = /* @__PURE__ */ new Map();
  const queue = createQueue();
  queue.enqueue({ project: defaultProject, location: initialLocation });
  forEachProjectInProjects(projects, initialLocation.fileName, (project, path) => {
    const location = { fileName: path, pos: initialLocation.pos };
    queue.enqueue({ project, location });
  });
  const projectService = defaultProject.projectService;
  const cancellationToken = defaultProject.getCancellationToken();
  const defaultDefinition = getDefinitionLocation(defaultProject, initialLocation, isForRename);
  const getGeneratedDefinition = memoize(
    () => defaultProject.isSourceOfProjectReferenceRedirect(defaultDefinition.fileName) ? defaultDefinition : defaultProject.getLanguageService().getSourceMapper().tryGetGeneratedPosition(defaultDefinition)
  );
  const getSourceDefinition = memoize(
    () => defaultProject.isSourceOfProjectReferenceRedirect(defaultDefinition.fileName) ? defaultDefinition : defaultProject.getLanguageService().getSourceMapper().tryGetSourcePosition(defaultDefinition)
  );
  const searchedProjectKeys = /* @__PURE__ */ new Set();
  onCancellation:
    while (!queue.isEmpty()) {
      while (!queue.isEmpty()) {
        if (cancellationToken.isCancellationRequested()) break onCancellation;
        const { project, location } = queue.dequeue();
        if (resultsMap.has(project)) continue;
        if (isLocationProjectReferenceRedirect(project, location)) continue;
        updateProjectIfDirty(project);
        if (!project.containsFile(toNormalizedPath(location.fileName))) {
          continue;
        }
        const projectResults = searchPosition(project, location);
        resultsMap.set(project, projectResults ?? emptyArray2);
        searchedProjectKeys.add(getProjectKey(project));
      }
      if (defaultDefinition) {
        projectService.loadAncestorProjectTree(searchedProjectKeys);
        projectService.forEachEnabledProject((project) => {
          if (cancellationToken.isCancellationRequested()) return;
          if (resultsMap.has(project)) return;
          const location = mapDefinitionInProject(defaultDefinition, project, getGeneratedDefinition, getSourceDefinition);
          if (location) {
            queue.enqueue({ project, location });
          }
        });
      }
    }
  if (resultsMap.size === 1) {
    return firstIterator(resultsMap.values());
  }
  return resultsMap;
  function searchPosition(project, location) {
    const projectResults = getResultsForPosition(project, location);
    if (!projectResults) return void 0;
    for (const result of projectResults) {
      forPositionInResult(result, (position) => {
        const originalLocation = projectService.getOriginalLocationEnsuringConfiguredProject(project, position);
        if (!originalLocation) return;
        const originalScriptInfo = projectService.getScriptInfo(originalLocation.fileName);
        for (const project2 of originalScriptInfo.containingProjects) {
          if (!project2.isOrphan() && !resultsMap.has(project2)) {
            queue.enqueue({ project: project2, location: originalLocation });
          }
        }
        const symlinkedProjectsMap = projectService.getSymlinkedProjects(originalScriptInfo);
        if (symlinkedProjectsMap) {
          symlinkedProjectsMap.forEach((symlinkedProjects, symlinkedPath) => {
            for (const symlinkedProject of symlinkedProjects) {
              if (!symlinkedProject.isOrphan() && !resultsMap.has(symlinkedProject)) {
                queue.enqueue({ project: symlinkedProject, location: { fileName: symlinkedPath, pos: originalLocation.pos } });
              }
            }
          });
        }
      });
    }
    return projectResults;
  }
}
function mapDefinitionInProject(definition, project, getGeneratedDefinition, getSourceDefinition) {
  if (project.containsFile(toNormalizedPath(definition.fileName)) && !isLocationProjectReferenceRedirect(project, definition)) {
    return definition;
  }
  const generatedDefinition = getGeneratedDefinition();
  if (generatedDefinition && project.containsFile(toNormalizedPath(generatedDefinition.fileName))) return generatedDefinition;
  const sourceDefinition = getSourceDefinition();
  return sourceDefinition && project.containsFile(toNormalizedPath(sourceDefinition.fileName)) ? sourceDefinition : void 0;
}
function isLocationProjectReferenceRedirect(project, location) {
  if (!location) return false;
  const program = project.getLanguageService().getProgram();
  if (!program) return false;
  const sourceFile = program.getSourceFile(location.fileName);
  return !!sourceFile && sourceFile.resolvedPath !== sourceFile.path && sourceFile.resolvedPath !== project.toPath(location.fileName);
}
function getProjectKey(project) {
  return isConfiguredProject(project) ? project.canonicalConfigFilePath : project.getProjectName();
}
function documentSpanLocation({ fileName, textSpan }) {
  return { fileName, pos: textSpan.start };
}
function getMappedLocationForProject(location, project) {
  return getMappedLocation(location, project.getSourceMapper(), (p) => project.projectService.fileExists(p));
}
function getMappedDocumentSpanForProject(documentSpan, project) {
  return getMappedDocumentSpan(documentSpan, project.getSourceMapper(), (p) => project.projectService.fileExists(p));
}
function getMappedContextSpanForProject(documentSpan, project) {
  return getMappedContextSpan(documentSpan, project.getSourceMapper(), (p) => project.projectService.fileExists(p));
}
var invalidPartialSemanticModeCommands = [
  "openExternalProject" /* OpenExternalProject */,
  "openExternalProjects" /* OpenExternalProjects */,
  "closeExternalProject" /* CloseExternalProject */,
  "synchronizeProjectList" /* SynchronizeProjectList */,
  "emit-output" /* EmitOutput */,
  "compileOnSaveAffectedFileList" /* CompileOnSaveAffectedFileList */,
  "compileOnSaveEmitFile" /* CompileOnSaveEmitFile */,
  "compilerOptionsDiagnostics-full" /* CompilerOptionsDiagnosticsFull */,
  "encodedSemanticClassifications-full" /* EncodedSemanticClassificationsFull */,
  "semanticDiagnosticsSync" /* SemanticDiagnosticsSync */,
  "suggestionDiagnosticsSync" /* SuggestionDiagnosticsSync */,
  "geterrForProject" /* GeterrForProject */,
  "reload" /* Reload */,
  "reloadProjects" /* ReloadProjects */,
  "getCodeFixes" /* GetCodeFixes */,
  "getCodeFixes-full" /* GetCodeFixesFull */,
  "getCombinedCodeFix" /* GetCombinedCodeFix */,
  "getCombinedCodeFix-full" /* GetCombinedCodeFixFull */,
  "applyCodeActionCommand" /* ApplyCodeActionCommand */,
  "getSupportedCodeFixes" /* GetSupportedCodeFixes */,
  "getApplicableRefactors" /* GetApplicableRefactors */,
  "getMoveToRefactoringFileSuggestions" /* GetMoveToRefactoringFileSuggestions */,
  "getEditsForRefactor" /* GetEditsForRefactor */,
  "getEditsForRefactor-full" /* GetEditsForRefactorFull */,
  "organizeImports" /* OrganizeImports */,
  "organizeImports-full" /* OrganizeImportsFull */,
  "getEditsForFileRename" /* GetEditsForFileRename */,
  "getEditsForFileRename-full" /* GetEditsForFileRenameFull */,
  "prepareCallHierarchy" /* PrepareCallHierarchy */,
  "provideCallHierarchyIncomingCalls" /* ProvideCallHierarchyIncomingCalls */,
  "provideCallHierarchyOutgoingCalls" /* ProvideCallHierarchyOutgoingCalls */,
  "getPasteEdits" /* GetPasteEdits */
];
var invalidSyntacticModeCommands = [
  ...invalidPartialSemanticModeCommands,
  "definition" /* Definition */,
  "definition-full" /* DefinitionFull */,
  "definitionAndBoundSpan" /* DefinitionAndBoundSpan */,
  "definitionAndBoundSpan-full" /* DefinitionAndBoundSpanFull */,
  "typeDefinition" /* TypeDefinition */,
  "implementation" /* Implementation */,
  "implementation-full" /* ImplementationFull */,
  "references" /* References */,
  "references-full" /* ReferencesFull */,
  "rename" /* Rename */,
  "renameLocations-full" /* RenameLocationsFull */,
  "rename-full" /* RenameInfoFull */,
  "quickinfo" /* Quickinfo */,
  "quickinfo-full" /* QuickinfoFull */,
  "completionInfo" /* CompletionInfo */,
  "completions" /* Completions */,
  "completions-full" /* CompletionsFull */,
  "completionEntryDetails" /* CompletionDetails */,
  "completionEntryDetails-full" /* CompletionDetailsFull */,
  "signatureHelp" /* SignatureHelp */,
  "signatureHelp-full" /* SignatureHelpFull */,
  "navto" /* Navto */,
  "navto-full" /* NavtoFull */,
  "documentHighlights" /* DocumentHighlights */,
  "documentHighlights-full" /* DocumentHighlightsFull */
];
var Session3 = class _Session {
  constructor(opts) {
    this.changeSeq = 0;
    // Minimum number of lines for attempting to use region diagnostics for a file.
    /** @internal */
    this.regionDiagLineCountThreshold = 500;
    this.handlers = new Map(Object.entries({
      // TODO(jakebailey): correctly type the handlers
      ["status" /* Status */]: () => {
        const response = { version };
        return this.requiredResponse(response);
      },
      ["openExternalProject" /* OpenExternalProject */]: (request) => {
        this.projectService.openExternalProject(
          request.arguments,
          /*cleanupAfter*/
          true
        );
        return this.requiredResponse(
          /*response*/
          true
        );
      },
      ["openExternalProjects" /* OpenExternalProjects */]: (request) => {
        this.projectService.openExternalProjects(request.arguments.projects);
        return this.requiredResponse(
          /*response*/
          true
        );
      },
      ["closeExternalProject" /* CloseExternalProject */]: (request) => {
        this.projectService.closeExternalProject(
          request.arguments.projectFileName,
          /*cleanupAfter*/
          true
        );
        return this.requiredResponse(
          /*response*/
          true
        );
      },
      ["synchronizeProjectList" /* SynchronizeProjectList */]: (request) => {
        const result = this.projectService.synchronizeProjectList(request.arguments.knownProjects, request.arguments.includeProjectReferenceRedirectInfo);
        if (!result.some((p) => p.projectErrors && p.projectErrors.length !== 0)) {
          return this.requiredResponse(result);
        }
        const converted = map(result, (p) => {
          if (!p.projectErrors || p.projectErrors.length === 0) {
            return p;
          }
          return {
            info: p.info,
            changes: p.changes,
            files: p.files,
            projectErrors: this.convertToDiagnosticsWithLinePosition(
              p.projectErrors,
              /*scriptInfo*/
              void 0
            )
          };
        });
        return this.requiredResponse(converted);
      },
      ["updateOpen" /* UpdateOpen */]: (request) => {
        this.changeSeq++;
        this.projectService.applyChangesInOpenFiles(
          request.arguments.openFiles && mapIterator(request.arguments.openFiles, (file) => ({
            fileName: file.file,
            content: file.fileContent,
            scriptKind: file.scriptKindName,
            projectRootPath: file.projectRootPath
          })),
          request.arguments.changedFiles && mapIterator(request.arguments.changedFiles, (file) => ({
            fileName: file.fileName,
            changes: mapDefinedIterator(arrayReverseIterator(file.textChanges), (change) => {
              const scriptInfo = Debug.checkDefined(this.projectService.getScriptInfo(file.fileName));
              const start = scriptInfo.lineOffsetToPosition(change.start.line, change.start.offset);
              const end = scriptInfo.lineOffsetToPosition(change.end.line, change.end.offset);
              return start >= 0 ? { span: { start, length: end - start }, newText: change.newText } : void 0;
            })
          })),
          request.arguments.closedFiles
        );
        return this.requiredResponse(
          /*response*/
          true
        );
      },
      ["applyChangedToOpenFiles" /* ApplyChangedToOpenFiles */]: (request) => {
        this.changeSeq++;
        this.projectService.applyChangesInOpenFiles(
          request.arguments.openFiles,
          request.arguments.changedFiles && mapIterator(request.arguments.changedFiles, (file) => ({
            fileName: file.fileName,
            // apply changes in reverse order
            changes: arrayReverseIterator(file.changes)
          })),
          request.arguments.closedFiles
        );
        return this.requiredResponse(
          /*response*/
          true
        );
      },
      ["exit" /* Exit */]: () => {
        this.exit();
        return this.notRequired(
          /*request*/
          void 0
        );
      },
      ["definition" /* Definition */]: (request) => {
        return this.requiredResponse(this.getDefinition(
          request.arguments,
          /*simplifiedResult*/
          true
        ));
      },
      ["definition-full" /* DefinitionFull */]: (request) => {
        return this.requiredResponse(this.getDefinition(
          request.arguments,
          /*simplifiedResult*/
          false
        ));
      },
      ["definitionAndBoundSpan" /* DefinitionAndBoundSpan */]: (request) => {
        return this.requiredResponse(this.getDefinitionAndBoundSpan(
          request.arguments,
          /*simplifiedResult*/
          true
        ));
      },
      ["definitionAndBoundSpan-full" /* DefinitionAndBoundSpanFull */]: (request) => {
        return this.requiredResponse(this.getDefinitionAndBoundSpan(
          request.arguments,
          /*simplifiedResult*/
          false
        ));
      },
      ["findSourceDefinition" /* FindSourceDefinition */]: (request) => {
        return this.requiredResponse(this.findSourceDefinition(request.arguments));
      },
      ["emit-output" /* EmitOutput */]: (request) => {
        return this.requiredResponse(this.getEmitOutput(request.arguments));
      },
      ["typeDefinition" /* TypeDefinition */]: (request) => {
        return this.requiredResponse(this.getTypeDefinition(request.arguments));
      },
      ["implementation" /* Implementation */]: (request) => {
        return this.requiredResponse(this.getImplementation(
          request.arguments,
          /*simplifiedResult*/
          true
        ));
      },
      ["implementation-full" /* ImplementationFull */]: (request) => {
        return this.requiredResponse(this.getImplementation(
          request.arguments,
          /*simplifiedResult*/
          false
        ));
      },
      ["references" /* References */]: (request) => {
        return this.requiredResponse(this.getReferences(
          request.arguments,
          /*simplifiedResult*/
          true
        ));
      },
      ["references-full" /* ReferencesFull */]: (request) => {
        return this.requiredResponse(this.getReferences(
          request.arguments,
          /*simplifiedResult*/
          false
        ));
      },
      ["rename" /* Rename */]: (request) => {
        return this.requiredResponse(this.getRenameLocations(
          request.arguments,
          /*simplifiedResult*/
          true
        ));
      },
      ["renameLocations-full" /* RenameLocationsFull */]: (request) => {
        return this.requiredResponse(this.getRenameLocations(
          request.arguments,
          /*simplifiedResult*/
          false
        ));
      },
      ["rename-full" /* RenameInfoFull */]: (request) => {
        return this.requiredResponse(this.getRenameInfo(request.arguments));
      },
      ["open" /* Open */]: (request) => {
        this.openClientFile(
          toNormalizedPath(request.arguments.file),
          request.arguments.fileContent,
          convertScriptKindName(request.arguments.scriptKindName),
          // TODO: GH#18217
          request.arguments.projectRootPath ? toNormalizedPath(request.arguments.projectRootPath) : void 0
        );
        return this.notRequired(request);
      },
      ["quickinfo" /* Quickinfo */]: (request) => {
        return this.requiredResponse(this.getQuickInfoWorker(
          request.arguments,
          /*simplifiedResult*/
          true
        ));
      },
      ["quickinfo-full" /* QuickinfoFull */]: (request) => {
        return this.requiredResponse(this.getQuickInfoWorker(
          request.arguments,
          /*simplifiedResult*/
          false
        ));
      },
      ["getOutliningSpans" /* GetOutliningSpans */]: (request) => {
        return this.requiredResponse(this.getOutliningSpans(
          request.arguments,
          /*simplifiedResult*/
          true
        ));
      },
      ["outliningSpans" /* GetOutliningSpansFull */]: (request) => {
        return this.requiredResponse(this.getOutliningSpans(
          request.arguments,
          /*simplifiedResult*/
          false
        ));
      },
      ["todoComments" /* TodoComments */]: (request) => {
        return this.requiredResponse(this.getTodoComments(request.arguments));
      },
      ["indentation" /* Indentation */]: (request) => {
        return this.requiredResponse(this.getIndentation(request.arguments));
      },
      ["nameOrDottedNameSpan" /* NameOrDottedNameSpan */]: (request) => {
        return this.requiredResponse(this.getNameOrDottedNameSpan(request.arguments));
      },
      ["breakpointStatement" /* BreakpointStatement */]: (request) => {
        return this.requiredResponse(this.getBreakpointStatement(request.arguments));
      },
      ["braceCompletion" /* BraceCompletion */]: (request) => {
        return this.requiredResponse(this.isValidBraceCompletion(request.arguments));
      },
      ["docCommentTemplate" /* DocCommentTemplate */]: (request) => {
        return this.requiredResponse(this.getDocCommentTemplate(request.arguments));
      },
      ["getSpanOfEnclosingComment" /* GetSpanOfEnclosingComment */]: (request) => {
        return this.requiredResponse(this.getSpanOfEnclosingComment(request.arguments));
      },
      ["fileReferences" /* FileReferences */]: (request) => {
        return this.requiredResponse(this.getFileReferences(
          request.arguments,
          /*simplifiedResult*/
          true
        ));
      },
      ["fileReferences-full" /* FileReferencesFull */]: (request) => {
        return this.requiredResponse(this.getFileReferences(
          request.arguments,
          /*simplifiedResult*/
          false
        ));
      },
      ["format" /* Format */]: (request) => {
        return this.requiredResponse(this.getFormattingEditsForRange(request.arguments));
      },
      ["formatonkey" /* Formatonkey */]: (request) => {
        return this.requiredResponse(this.getFormattingEditsAfterKeystroke(request.arguments));
      },
      ["format-full" /* FormatFull */]: (request) => {
        return this.requiredResponse(this.getFormattingEditsForDocumentFull(request.arguments));
      },
      ["formatonkey-full" /* FormatonkeyFull */]: (request) => {
        return this.requiredResponse(this.getFormattingEditsAfterKeystrokeFull(request.arguments));
      },
      ["formatRange-full" /* FormatRangeFull */]: (request) => {
        return this.requiredResponse(this.getFormattingEditsForRangeFull(request.arguments));
      },
      ["completionInfo" /* CompletionInfo */]: (request) => {
        return this.requiredResponse(this.getCompletions(request.arguments, "completionInfo" /* CompletionInfo */));
      },
      ["completions" /* Completions */]: (request) => {
        return this.requiredResponse(this.getCompletions(request.arguments, "completions" /* Completions */));
      },
      ["completions-full" /* CompletionsFull */]: (request) => {
        return this.requiredResponse(this.getCompletions(request.arguments, "completions-full" /* CompletionsFull */));
      },
      ["completionEntryDetails" /* CompletionDetails */]: (request) => {
        return this.requiredResponse(this.getCompletionEntryDetails(
          request.arguments,
          /*fullResult*/
          false
        ));
      },
      ["completionEntryDetails-full" /* CompletionDetailsFull */]: (request) => {
        return this.requiredResponse(this.getCompletionEntryDetails(
          request.arguments,
          /*fullResult*/
          true
        ));
      },
      ["compileOnSaveAffectedFileList" /* CompileOnSaveAffectedFileList */]: (request) => {
        return this.requiredResponse(this.getCompileOnSaveAffectedFileList(request.arguments));
      },
      ["compileOnSaveEmitFile" /* CompileOnSaveEmitFile */]: (request) => {
        return this.requiredResponse(this.emitFile(request.arguments));
      },
      ["signatureHelp" /* SignatureHelp */]: (request) => {
        return this.requiredResponse(this.getSignatureHelpItems(
          request.arguments,
          /*simplifiedResult*/
          true
        ));
      },
      ["signatureHelp-full" /* SignatureHelpFull */]: (request) => {
        return this.requiredResponse(this.getSignatureHelpItems(
          request.arguments,
          /*simplifiedResult*/
          false
        ));
      },
      ["compilerOptionsDiagnostics-full" /* CompilerOptionsDiagnosticsFull */]: (request) => {
        return this.requiredResponse(this.getCompilerOptionsDiagnostics(request.arguments));
      },
      ["encodedSyntacticClassifications-full" /* EncodedSyntacticClassificationsFull */]: (request) => {
        return this.requiredResponse(this.getEncodedSyntacticClassifications(request.arguments));
      },
      ["encodedSemanticClassifications-full" /* EncodedSemanticClassificationsFull */]: (request) => {
        return this.requiredResponse(this.getEncodedSemanticClassifications(request.arguments));
      },
      ["cleanup" /* Cleanup */]: () => {
        this.cleanup();
        return this.requiredResponse(
          /*response*/
          true
        );
      },
      ["semanticDiagnosticsSync" /* SemanticDiagnosticsSync */]: (request) => {
        return this.requiredResponse(this.getSemanticDiagnosticsSync(request.arguments));
      },
      ["syntacticDiagnosticsSync" /* SyntacticDiagnosticsSync */]: (request) => {
        return this.requiredResponse(this.getSyntacticDiagnosticsSync(request.arguments));
      },
      ["suggestionDiagnosticsSync" /* SuggestionDiagnosticsSync */]: (request) => {
        return this.requiredResponse(this.getSuggestionDiagnosticsSync(request.arguments));
      },
      ["geterr" /* Geterr */]: (request) => {
        this.errorCheck.startNew((next) => this.getDiagnostics(next, request.arguments.delay, request.arguments.files));
        return this.notRequired(
          /*request*/
          void 0
        );
      },
      ["geterrForProject" /* GeterrForProject */]: (request) => {
        this.errorCheck.startNew((next) => this.getDiagnosticsForProject(next, request.arguments.delay, request.arguments.file));
        return this.notRequired(
          /*request*/
          void 0
        );
      },
      ["change" /* Change */]: (request) => {
        this.change(request.arguments);
        return this.notRequired(request);
      },
      ["configure" /* Configure */]: (request) => {
        this.projectService.setHostConfiguration(request.arguments);
        return this.notRequired(request);
      },
      ["reload" /* Reload */]: (request) => {
        this.reload(request.arguments);
        return this.requiredResponse({ reloadFinished: true });
      },
      ["saveto" /* Saveto */]: (request) => {
        const savetoArgs = request.arguments;
        this.saveToTmp(savetoArgs.file, savetoArgs.tmpfile);
        return this.notRequired(request);
      },
      ["close" /* Close */]: (request) => {
        const closeArgs = request.arguments;
        this.closeClientFile(closeArgs.file);
        return this.notRequired(request);
      },
      ["navto" /* Navto */]: (request) => {
        return this.requiredResponse(this.getNavigateToItems(
          request.arguments,
          /*simplifiedResult*/
          true
        ));
      },
      ["navto-full" /* NavtoFull */]: (request) => {
        return this.requiredResponse(this.getNavigateToItems(
          request.arguments,
          /*simplifiedResult*/
          false
        ));
      },
      ["brace" /* Brace */]: (request) => {
        return this.requiredResponse(this.getBraceMatching(
          request.arguments,
          /*simplifiedResult*/
          true
        ));
      },
      ["brace-full" /* BraceFull */]: (request) => {
        return this.requiredResponse(this.getBraceMatching(
          request.arguments,
          /*simplifiedResult*/
          false
        ));
      },
      ["navbar" /* NavBar */]: (request) => {
        return this.requiredResponse(this.getNavigationBarItems(
          request.arguments,
          /*simplifiedResult*/
          true
        ));
      },
      ["navbar-full" /* NavBarFull */]: (request) => {
        return this.requiredResponse(this.getNavigationBarItems(
          request.arguments,
          /*simplifiedResult*/
          false
        ));
      },
      ["navtree" /* NavTree */]: (request) => {
        return this.requiredResponse(this.getNavigationTree(
          request.arguments,
          /*simplifiedResult*/
          true
        ));
      },
      ["navtree-full" /* NavTreeFull */]: (request) => {
        return this.requiredResponse(this.getNavigationTree(
          request.arguments,
          /*simplifiedResult*/
          false
        ));
      },
      ["documentHighlights" /* DocumentHighlights */]: (request) => {
        return this.requiredResponse(this.getDocumentHighlights(
          request.arguments,
          /*simplifiedResult*/
          true
        ));
      },
      ["documentHighlights-full" /* DocumentHighlightsFull */]: (request) => {
        return this.requiredResponse(this.getDocumentHighlights(
          request.arguments,
          /*simplifiedResult*/
          false
        ));
      },
      ["compilerOptionsForInferredProjects" /* CompilerOptionsForInferredProjects */]: (request) => {
        this.setCompilerOptionsForInferredProjects(request.arguments);
        return this.requiredResponse(
          /*response*/
          true
        );
      },
      ["projectInfo" /* ProjectInfo */]: (request) => {
        return this.requiredResponse(this.getProjectInfo(request.arguments));
      },
      ["reloadProjects" /* ReloadProjects */]: (request) => {
        this.projectService.reloadProjects();
        return this.notRequired(request);
      },
      ["jsxClosingTag" /* JsxClosingTag */]: (request) => {
        return this.requiredResponse(this.getJsxClosingTag(request.arguments));
      },
      ["linkedEditingRange" /* LinkedEditingRange */]: (request) => {
        return this.requiredResponse(this.getLinkedEditingRange(request.arguments));
      },
      ["getCodeFixes" /* GetCodeFixes */]: (request) => {
        return this.requiredResponse(this.getCodeFixes(
          request.arguments,
          /*simplifiedResult*/
          true
        ));
      },
      ["getCodeFixes-full" /* GetCodeFixesFull */]: (request) => {
        return this.requiredResponse(this.getCodeFixes(
          request.arguments,
          /*simplifiedResult*/
          false
        ));
      },
      ["getCombinedCodeFix" /* GetCombinedCodeFix */]: (request) => {
        return this.requiredResponse(this.getCombinedCodeFix(
          request.arguments,
          /*simplifiedResult*/
          true
        ));
      },
      ["getCombinedCodeFix-full" /* GetCombinedCodeFixFull */]: (request) => {
        return this.requiredResponse(this.getCombinedCodeFix(
          request.arguments,
          /*simplifiedResult*/
          false
        ));
      },
      ["applyCodeActionCommand" /* ApplyCodeActionCommand */]: (request) => {
        return this.requiredResponse(this.applyCodeActionCommand(request.arguments));
      },
      ["getSupportedCodeFixes" /* GetSupportedCodeFixes */]: (request) => {
        return this.requiredResponse(this.getSupportedCodeFixes(request.arguments));
      },
      ["getApplicableRefactors" /* GetApplicableRefactors */]: (request) => {
        return this.requiredResponse(this.getApplicableRefactors(request.arguments));
      },
      ["getEditsForRefactor" /* GetEditsForRefactor */]: (request) => {
        return this.requiredResponse(this.getEditsForRefactor(
          request.arguments,
          /*simplifiedResult*/
          true
        ));
      },
      ["getMoveToRefactoringFileSuggestions" /* GetMoveToRefactoringFileSuggestions */]: (request) => {
        return this.requiredResponse(this.getMoveToRefactoringFileSuggestions(request.arguments));
      },
      ["getPasteEdits" /* GetPasteEdits */]: (request) => {
        return this.requiredResponse(this.getPasteEdits(request.arguments));
      },
      ["getEditsForRefactor-full" /* GetEditsForRefactorFull */]: (request) => {
        return this.requiredResponse(this.getEditsForRefactor(
          request.arguments,
          /*simplifiedResult*/
          false
        ));
      },
      ["organizeImports" /* OrganizeImports */]: (request) => {
        return this.requiredResponse(this.organizeImports(
          request.arguments,
          /*simplifiedResult*/
          true
        ));
      },
      ["organizeImports-full" /* OrganizeImportsFull */]: (request) => {
        return this.requiredResponse(this.organizeImports(
          request.arguments,
          /*simplifiedResult*/
          false
        ));
      },
      ["getEditsForFileRename" /* GetEditsForFileRename */]: (request) => {
        return this.requiredResponse(this.getEditsForFileRename(
          request.arguments,
          /*simplifiedResult*/
          true
        ));
      },
      ["getEditsForFileRename-full" /* GetEditsForFileRenameFull */]: (request) => {
        return this.requiredResponse(this.getEditsForFileRename(
          request.arguments,
          /*simplifiedResult*/
          false
        ));
      },
      ["configurePlugin" /* ConfigurePlugin */]: (request) => {
        this.configurePlugin(request.arguments);
        return this.notRequired(request);
      },
      ["selectionRange" /* SelectionRange */]: (request) => {
        return this.requiredResponse(this.getSmartSelectionRange(
          request.arguments,
          /*simplifiedResult*/
          true
        ));
      },
      ["selectionRange-full" /* SelectionRangeFull */]: (request) => {
        return this.requiredResponse(this.getSmartSelectionRange(
          request.arguments,
          /*simplifiedResult*/
          false
        ));
      },
      ["prepareCallHierarchy" /* PrepareCallHierarchy */]: (request) => {
        return this.requiredResponse(this.prepareCallHierarchy(request.arguments));
      },
      ["provideCallHierarchyIncomingCalls" /* ProvideCallHierarchyIncomingCalls */]: (request) => {
        return this.requiredResponse(this.provideCallHierarchyIncomingCalls(request.arguments));
      },
      ["provideCallHierarchyOutgoingCalls" /* ProvideCallHierarchyOutgoingCalls */]: (request) => {
        return this.requiredResponse(this.provideCallHierarchyOutgoingCalls(request.arguments));
      },
      ["toggleLineComment" /* ToggleLineComment */]: (request) => {
        return this.requiredResponse(this.toggleLineComment(
          request.arguments,
          /*simplifiedResult*/
          true
        ));
      },
      ["toggleLineComment-full" /* ToggleLineCommentFull */]: (request) => {
        return this.requiredResponse(this.toggleLineComment(
          request.arguments,
          /*simplifiedResult*/
          false
        ));
      },
      ["toggleMultilineComment" /* ToggleMultilineComment */]: (request) => {
        return this.requiredResponse(this.toggleMultilineComment(
          request.arguments,
          /*simplifiedResult*/
          true
        ));
      },
      ["toggleMultilineComment-full" /* ToggleMultilineCommentFull */]: (request) => {
        return this.requiredResponse(this.toggleMultilineComment(
          request.arguments,
          /*simplifiedResult*/
          false
        ));
      },
      ["commentSelection" /* CommentSelection */]: (request) => {
        return this.requiredResponse(this.commentSelection(
          request.arguments,
          /*simplifiedResult*/
          true
        ));
      },
      ["commentSelection-full" /* CommentSelectionFull */]: (request) => {
        return this.requiredResponse(this.commentSelection(
          request.arguments,
          /*simplifiedResult*/
          false
        ));
      },
      ["uncommentSelection" /* UncommentSelection */]: (request) => {
        return this.requiredResponse(this.uncommentSelection(
          request.arguments,
          /*simplifiedResult*/
          true
        ));
      },
      ["uncommentSelection-full" /* UncommentSelectionFull */]: (request) => {
        return this.requiredResponse(this.uncommentSelection(
          request.arguments,
          /*simplifiedResult*/
          false
        ));
      },
      ["provideInlayHints" /* ProvideInlayHints */]: (request) => {
        return this.requiredResponse(this.provideInlayHints(request.arguments));
      },
      ["mapCode" /* MapCode */]: (request) => {
        return this.requiredResponse(this.mapCode(request.arguments));
      }
    }));
    this.host = opts.host;
    this.cancellationToken = opts.cancellationToken;
    this.typingsInstaller = opts.typingsInstaller || nullTypingsInstaller;
    this.byteLength = opts.byteLength;
    this.hrtime = opts.hrtime;
    this.logger = opts.logger;
    this.canUseEvents = opts.canUseEvents;
    this.suppressDiagnosticEvents = opts.suppressDiagnosticEvents;
    this.noGetErrOnBackgroundUpdate = opts.noGetErrOnBackgroundUpdate;
    const { throttleWaitMilliseconds } = opts;
    this.eventHandler = this.canUseEvents ? opts.eventHandler || ((event) => this.defaultEventHandler(event)) : void 0;
    const multistepOperationHost = {
      executeWithRequestId: (requestId, action, performanceData) => this.executeWithRequestId(requestId, action, performanceData),
      getCurrentRequestId: () => this.currentRequestId,
      getPerformanceData: () => this.performanceData,
      getServerHost: () => this.host,
      logError: (err, cmd) => this.logError(err, cmd),
      sendRequestCompletedEvent: (requestId, performanceData) => this.sendRequestCompletedEvent(requestId, performanceData),
      isCancellationRequested: () => this.cancellationToken.isCancellationRequested()
    };
    this.errorCheck = new MultistepOperation(multistepOperationHost);
    const settings = {
      host: this.host,
      logger: this.logger,
      cancellationToken: this.cancellationToken,
      useSingleInferredProject: opts.useSingleInferredProject,
      useInferredProjectPerProjectRoot: opts.useInferredProjectPerProjectRoot,
      typingsInstaller: this.typingsInstaller,
      throttleWaitMilliseconds,
      eventHandler: this.eventHandler,
      suppressDiagnosticEvents: this.suppressDiagnosticEvents,
      globalPlugins: opts.globalPlugins,
      pluginProbeLocations: opts.pluginProbeLocations,
      allowLocalPluginLoads: opts.allowLocalPluginLoads,
      typesMapLocation: opts.typesMapLocation,
      serverMode: opts.serverMode,
      session: this,
      canUseWatchEvents: opts.canUseWatchEvents,
      incrementalVerifier: opts.incrementalVerifier
    };
    this.projectService = new ProjectService2(settings);
    this.projectService.setPerformanceEventHandler(this.performanceEventHandler.bind(this));
    this.gcTimer = new GcTimer(
      this.host,
      /*delay*/
      7e3,
      this.logger
    );
    switch (this.projectService.serverMode) {
      case 0 /* Semantic */:
        break;
      case 1 /* PartialSemantic */:
        invalidPartialSemanticModeCommands.forEach(
          (commandName) => this.handlers.set(commandName, (request) => {
            throw new Error(`Request: ${request.command} not allowed in LanguageServiceMode.PartialSemantic`);
          })
        );
        break;
      case 2 /* Syntactic */:
        invalidSyntacticModeCommands.forEach(
          (commandName) => this.handlers.set(commandName, (request) => {
            throw new Error(`Request: ${request.command} not allowed in LanguageServiceMode.Syntactic`);
          })
        );
        break;
      default:
        Debug.assertNever(this.projectService.serverMode);
    }
  }
  sendRequestCompletedEvent(requestId, performanceData) {
    this.event(
      {
        request_seq: requestId,
        performanceData: performanceData && toProtocolPerformanceData(performanceData)
      },
      "requestCompleted"
    );
  }
  addPerformanceData(key, value) {
    if (!this.performanceData) {
      this.performanceData = {};
    }
    this.performanceData[key] = (this.performanceData[key] ?? 0) + value;
  }
  addDiagnosticsPerformanceData(file, kind, duration) {
    var _a, _b;
    if (!this.performanceData) {
      this.performanceData = {};
    }
    let fileDiagnosticDuration = (_a = this.performanceData.diagnosticsDuration) == null ? void 0 : _a.get(file);
    if (!fileDiagnosticDuration) ((_b = this.performanceData).diagnosticsDuration ?? (_b.diagnosticsDuration = /* @__PURE__ */ new Map())).set(file, fileDiagnosticDuration = {});
    fileDiagnosticDuration[kind] = duration;
  }
  performanceEventHandler(event) {
    switch (event.kind) {
      case "UpdateGraph":
        this.addPerformanceData("updateGraphDurationMs", event.durationMs);
        break;
      case "CreatePackageJsonAutoImportProvider":
        this.addPerformanceData("createAutoImportProviderProgramDurationMs", event.durationMs);
        break;
    }
  }
  defaultEventHandler(event) {
    switch (event.eventName) {
      case ProjectsUpdatedInBackgroundEvent:
        this.projectsUpdatedInBackgroundEvent(event.data.openFiles);
        break;
      case ProjectLoadingStartEvent:
        this.event({
          projectName: event.data.project.getProjectName(),
          reason: event.data.reason
        }, event.eventName);
        break;
      case ProjectLoadingFinishEvent:
        this.event({
          projectName: event.data.project.getProjectName()
        }, event.eventName);
        break;
      case LargeFileReferencedEvent:
      case CreateFileWatcherEvent:
      case CreateDirectoryWatcherEvent:
      case CloseFileWatcherEvent:
        this.event(event.data, event.eventName);
        break;
      case ConfigFileDiagEvent:
        this.event({
          triggerFile: event.data.triggerFile,
          configFile: event.data.configFileName,
          diagnostics: map(event.data.diagnostics, (diagnostic) => formatDiagnosticToProtocol(
            diagnostic,
            /*includeFileName*/
            true
          ))
        }, event.eventName);
        break;
      case ProjectLanguageServiceStateEvent: {
        this.event({
          projectName: event.data.project.getProjectName(),
          languageServiceEnabled: event.data.languageServiceEnabled
        }, event.eventName);
        break;
      }
      case ProjectInfoTelemetryEvent: {
        const eventName = "telemetry";
        this.event({
          telemetryEventName: event.eventName,
          payload: event.data
        }, eventName);
        break;
      }
    }
  }
  projectsUpdatedInBackgroundEvent(openFiles) {
    this.projectService.logger.info(`got projects updated in background ${openFiles}`);
    if (openFiles.length) {
      if (!this.suppressDiagnosticEvents && !this.noGetErrOnBackgroundUpdate) {
        this.projectService.logger.info(`Queueing diagnostics update for ${openFiles}`);
        this.errorCheck.startNew((next) => this.updateErrorCheck(
          next,
          openFiles,
          100,
          /*requireOpen*/
          true
        ));
      }
      this.event({
        openFiles
      }, ProjectsUpdatedInBackgroundEvent);
    }
  }
  logError(err, cmd) {
    this.logErrorWorker(err, cmd);
  }
  logErrorWorker(err, cmd, fileRequest) {
    let msg = "Exception on executing command " + cmd;
    if (err.message) {
      msg += ":\n" + indent2(err.message);
      if (err.stack) {
        msg += "\n" + indent2(err.stack);
      }
    }
    if (this.logger.hasLevel(3 /* verbose */)) {
      if (fileRequest) {
        try {
          const { file, project } = this.getFileAndProject(fileRequest);
          const scriptInfo = project.getScriptInfoForNormalizedPath(file);
          if (scriptInfo) {
            const text = getSnapshotText(scriptInfo.getSnapshot());
            msg += `

File text of ${fileRequest.file}:${indent2(text)}
`;
          }
        } catch {
        }
      }
      if (err.ProgramFiles) {
        msg += `

Program files: ${JSON.stringify(err.ProgramFiles)}
`;
        msg += `

Projects::
`;
        let counter = 0;
        const addProjectInfo = (project) => {
          msg += `
Project '${project.projectName}' (${ProjectKind[project.projectKind]}) ${counter}
`;
          msg += project.filesToString(
            /*writeProjectFileNames*/
            true
          );
          msg += "\n-----------------------------------------------\n";
          counter++;
        };
        this.projectService.externalProjects.forEach(addProjectInfo);
        this.projectService.configuredProjects.forEach(addProjectInfo);
        this.projectService.inferredProjects.forEach(addProjectInfo);
      }
    }
    this.logger.msg(msg, "Err" /* Err */);
  }
  send(msg) {
    if (msg.type === "event" && !this.canUseEvents) {
      if (this.logger.hasLevel(3 /* verbose */)) {
        this.logger.info(`Session does not support events: ignored event: ${stringifyIndented(msg)}`);
      }
      return;
    }
    this.writeMessage(msg);
  }
  writeMessage(msg) {
    const msgText = formatMessage2(msg, this.logger, this.byteLength, this.host.newLine);
    this.host.write(msgText);
  }
  event(body, eventName) {
    this.send(toEvent(eventName, body));
  }
  /** @internal */
  doOutput(info, cmdName, reqSeq, success, performanceData, message) {
    const res = {
      seq: 0,
      type: "response",
      command: cmdName,
      request_seq: reqSeq,
      success,
      performanceData: performanceData && toProtocolPerformanceData(performanceData)
    };
    if (success) {
      let metadata;
      if (isArray(info)) {
        res.body = info;
        metadata = info.metadata;
        delete info.metadata;
      } else if (typeof info === "object") {
        if (info.metadata) {
          const { metadata: infoMetadata, ...body } = info;
          res.body = body;
          metadata = infoMetadata;
        } else {
          res.body = info;
        }
      } else {
        res.body = info;
      }
      if (metadata) res.metadata = metadata;
    } else {
      Debug.assert(info === void 0);
    }
    if (message) {
      res.message = message;
    }
    this.send(res);
  }
  semanticCheck(file, project) {
    var _a, _b;
    const diagnosticsStartTime = timestamp();
    (_a = tracing) == null ? void 0 : _a.push(tracing.Phase.Session, "semanticCheck", { file, configFilePath: project.canonicalConfigFilePath });
    const diags = isDeclarationFileInJSOnlyNonConfiguredProject(project, file) ? emptyArray2 : project.getLanguageService().getSemanticDiagnostics(file).filter((d) => !!d.file);
    this.sendDiagnosticsEvent(file, project, diags, "semanticDiag", diagnosticsStartTime);
    (_b = tracing) == null ? void 0 : _b.pop();
  }
  syntacticCheck(file, project) {
    var _a, _b;
    const diagnosticsStartTime = timestamp();
    (_a = tracing) == null ? void 0 : _a.push(tracing.Phase.Session, "syntacticCheck", { file, configFilePath: project.canonicalConfigFilePath });
    this.sendDiagnosticsEvent(file, project, project.getLanguageService().getSyntacticDiagnostics(file), "syntaxDiag", diagnosticsStartTime);
    (_b = tracing) == null ? void 0 : _b.pop();
  }
  suggestionCheck(file, project) {
    var _a, _b;
    const diagnosticsStartTime = timestamp();
    (_a = tracing) == null ? void 0 : _a.push(tracing.Phase.Session, "suggestionCheck", { file, configFilePath: project.canonicalConfigFilePath });
    this.sendDiagnosticsEvent(file, project, project.getLanguageService().getSuggestionDiagnostics(file), "suggestionDiag", diagnosticsStartTime);
    (_b = tracing) == null ? void 0 : _b.pop();
  }
  regionSemanticCheck(file, project, ranges) {
    var _a, _b, _c;
    const diagnosticsStartTime = timestamp();
    (_a = tracing) == null ? void 0 : _a.push(tracing.Phase.Session, "regionSemanticCheck", { file, configFilePath: project.canonicalConfigFilePath });
    let diagnosticsResult;
    if (!this.shouldDoRegionCheck(file) || !(diagnosticsResult = project.getLanguageService().getRegionSemanticDiagnostics(file, ranges))) {
      (_b = tracing) == null ? void 0 : _b.pop();
      return;
    }
    this.sendDiagnosticsEvent(file, project, diagnosticsResult.diagnostics, "regionSemanticDiag", diagnosticsStartTime, diagnosticsResult.spans);
    (_c = tracing) == null ? void 0 : _c.pop();
    return;
  }
  // We should only do the region-based semantic check if we think it would be
  // considerably faster than a whole-file semantic check.
  /** @internal */
  shouldDoRegionCheck(file) {
    var _a;
    const lineCount = (_a = this.projectService.getScriptInfoForNormalizedPath(file)) == null ? void 0 : _a.textStorage.getLineInfo().getLineCount();
    return !!(lineCount && lineCount >= this.regionDiagLineCountThreshold);
  }
  sendDiagnosticsEvent(file, project, diagnostics, kind, diagnosticsStartTime, spans) {
    try {
      const scriptInfo = Debug.checkDefined(project.getScriptInfo(file));
      const duration = timestamp() - diagnosticsStartTime;
      const body = {
        file,
        diagnostics: diagnostics.map((diag2) => formatDiag(file, project, diag2)),
        spans: spans == null ? void 0 : spans.map((span) => toProtocolTextSpan(span, scriptInfo))
      };
      this.event(
        body,
        kind
      );
      this.addDiagnosticsPerformanceData(file, kind, duration);
    } catch (err) {
      this.logError(err, kind);
    }
  }
  /** It is the caller's responsibility to verify that `!this.suppressDiagnosticEvents`. */
  updateErrorCheck(next, checkList, ms, requireOpen = true) {
    if (checkList.length === 0) {
      return;
    }
    Debug.assert(!this.suppressDiagnosticEvents);
    const seq = this.changeSeq;
    const followMs = Math.min(ms, 200);
    let index = 0;
    const goNext = () => {
      index++;
      if (checkList.length > index) {
        return next.delay("checkOne", followMs, checkOne);
      }
    };
    const doSemanticCheck = (fileName, project) => {
      this.semanticCheck(fileName, project);
      if (this.changeSeq !== seq) {
        return;
      }
      if (this.getPreferences(fileName).disableSuggestions) {
        return goNext();
      }
      next.immediate("suggestionCheck", () => {
        this.suggestionCheck(fileName, project);
        goNext();
      });
    };
    const checkOne = () => {
      if (this.changeSeq !== seq) {
        return;
      }
      let ranges;
      let item = checkList[index];
      if (isString(item)) {
        item = this.toPendingErrorCheck(item);
      } else if ("ranges" in item) {
        ranges = item.ranges;
        item = this.toPendingErrorCheck(item.file);
      }
      if (!item) {
        return goNext();
      }
      const { fileName, project } = item;
      updateProjectIfDirty(project);
      if (!project.containsFile(fileName, requireOpen)) {
        return;
      }
      this.syntacticCheck(fileName, project);
      if (this.changeSeq !== seq) {
        return;
      }
      if (project.projectService.serverMode !== 0 /* Semantic */) {
        return goNext();
      }
      if (ranges) {
        return next.immediate("regionSemanticCheck", () => {
          const scriptInfo = this.projectService.getScriptInfoForNormalizedPath(fileName);
          if (scriptInfo) {
            this.regionSemanticCheck(fileName, project, ranges.map((range) => this.getRange({ file: fileName, ...range }, scriptInfo)));
          }
          if (this.changeSeq !== seq) {
            return;
          }
          next.immediate("semanticCheck", () => doSemanticCheck(fileName, project));
        });
      }
      next.immediate("semanticCheck", () => doSemanticCheck(fileName, project));
    };
    if (checkList.length > index && this.changeSeq === seq) {
      next.delay("checkOne", ms, checkOne);
    }
  }
  cleanProjects(caption, projects) {
    if (!projects) {
      return;
    }
    this.logger.info(`cleaning ${caption}`);
    for (const p of projects) {
      p.getLanguageService(
        /*ensureSynchronized*/
        false
      ).cleanupSemanticCache();
      p.cleanupProgram();
    }
  }
  cleanup() {
    this.cleanProjects("inferred projects", this.projectService.inferredProjects);
    this.cleanProjects("configured projects", arrayFrom(this.projectService.configuredProjects.values()));
    this.cleanProjects("external projects", this.projectService.externalProjects);
    if (this.host.gc) {
      this.logger.info(`host.gc()`);
      this.host.gc();
    }
  }
  getEncodedSyntacticClassifications(args) {
    const { file, languageService } = this.getFileAndLanguageServiceForSyntacticOperation(args);
    return languageService.getEncodedSyntacticClassifications(file, args);
  }
  getEncodedSemanticClassifications(args) {
    const { file, project } = this.getFileAndProject(args);
    const format = args.format === "2020" ? "2020" /* TwentyTwenty */ : "original" /* Original */;
    return project.getLanguageService().getEncodedSemanticClassifications(file, args, format);
  }
  getProject(projectFileName) {
    return projectFileName === void 0 ? void 0 : this.projectService.findProject(projectFileName);
  }
  getConfigFileAndProject(args) {
    const project = this.getProject(args.projectFileName);
    const file = toNormalizedPath(args.file);
    return {
      configFile: project && project.hasConfigFile(file) ? file : void 0,
      project
    };
  }
  getConfigFileDiagnostics(configFile, project, includeLinePosition) {
    const projectErrors = project.getAllProjectErrors();
    const optionsErrors = project.getLanguageService().getCompilerOptionsDiagnostics();
    const diagnosticsForConfigFile = filter(
      concatenate(projectErrors, optionsErrors),
      (diagnostic) => !!diagnostic.file && diagnostic.file.fileName === configFile
    );
    return includeLinePosition ? this.convertToDiagnosticsWithLinePositionFromDiagnosticFile(diagnosticsForConfigFile) : map(
      diagnosticsForConfigFile,
      (diagnostic) => formatDiagnosticToProtocol(
        diagnostic,
        /*includeFileName*/
        false
      )
    );
  }
  convertToDiagnosticsWithLinePositionFromDiagnosticFile(diagnostics) {
    return diagnostics.map((d) => ({
      message: flattenDiagnosticMessageText(d.messageText, this.host.newLine),
      start: d.start,
      // TODO: GH#18217
      length: d.length,
      // TODO: GH#18217
      category: diagnosticCategoryName(d),
      code: d.code,
      source: d.source,
      startLocation: d.file && convertToLocation(getLineAndCharacterOfPosition(d.file, d.start)),
      // TODO: GH#18217
      endLocation: d.file && convertToLocation(getLineAndCharacterOfPosition(d.file, d.start + d.length)),
      // TODO: GH#18217
      reportsUnnecessary: d.reportsUnnecessary,
      reportsDeprecated: d.reportsDeprecated,
      relatedInformation: map(d.relatedInformation, formatRelatedInformation)
    }));
  }
  getCompilerOptionsDiagnostics(args) {
    const project = this.getProject(args.projectFileName);
    return this.convertToDiagnosticsWithLinePosition(
      filter(
        project.getLanguageService().getCompilerOptionsDiagnostics(),
        (diagnostic) => !diagnostic.file
      ),
      /*scriptInfo*/
      void 0
    );
  }
  convertToDiagnosticsWithLinePosition(diagnostics, scriptInfo) {
    return diagnostics.map(
      (d) => ({
        message: flattenDiagnosticMessageText(d.messageText, this.host.newLine),
        start: d.start,
        length: d.length,
        category: diagnosticCategoryName(d),
        code: d.code,
        source: d.source,
        startLocation: scriptInfo && scriptInfo.positionToLineOffset(d.start),
        // TODO: GH#18217
        endLocation: scriptInfo && scriptInfo.positionToLineOffset(d.start + d.length),
        reportsUnnecessary: d.reportsUnnecessary,
        reportsDeprecated: d.reportsDeprecated,
        relatedInformation: map(d.relatedInformation, formatRelatedInformation)
      })
    );
  }
  getDiagnosticsWorker(args, isSemantic, selector, includeLinePosition) {
    const { project, file } = this.getFileAndProject(args);
    if (isSemantic && isDeclarationFileInJSOnlyNonConfiguredProject(project, file)) {
      return emptyArray2;
    }
    const scriptInfo = project.getScriptInfoForNormalizedPath(file);
    const diagnostics = selector(project, file);
    return includeLinePosition ? this.convertToDiagnosticsWithLinePosition(diagnostics, scriptInfo) : diagnostics.map((d) => formatDiag(file, project, d));
  }
  getDefinition(args, simplifiedResult) {
    const { file, project } = this.getFileAndProject(args);
    const position = this.getPositionInFile(args, file);
    const definitions = this.mapDefinitionInfoLocations(project.getLanguageService().getDefinitionAtPosition(file, position) || emptyArray2, project);
    return simplifiedResult ? this.mapDefinitionInfo(definitions, project) : definitions.map(_Session.mapToOriginalLocation);
  }
  mapDefinitionInfoLocations(definitions, project) {
    return definitions.map((info) => {
      const newDocumentSpan = getMappedDocumentSpanForProject(info, project);
      return !newDocumentSpan ? info : {
        ...newDocumentSpan,
        containerKind: info.containerKind,
        containerName: info.containerName,
        kind: info.kind,
        name: info.name,
        failedAliasResolution: info.failedAliasResolution,
        ...info.unverified && { unverified: info.unverified }
      };
    });
  }
  getDefinitionAndBoundSpan(args, simplifiedResult) {
    const { file, project } = this.getFileAndProject(args);
    const position = this.getPositionInFile(args, file);
    const scriptInfo = Debug.checkDefined(project.getScriptInfo(file));
    const unmappedDefinitionAndBoundSpan = project.getLanguageService().getDefinitionAndBoundSpan(file, position);
    if (!unmappedDefinitionAndBoundSpan || !unmappedDefinitionAndBoundSpan.definitions) {
      return {
        definitions: emptyArray2,
        textSpan: void 0
        // TODO: GH#18217
      };
    }
    const definitions = this.mapDefinitionInfoLocations(unmappedDefinitionAndBoundSpan.definitions, project);
    const { textSpan } = unmappedDefinitionAndBoundSpan;
    if (simplifiedResult) {
      return {
        definitions: this.mapDefinitionInfo(definitions, project),
        textSpan: toProtocolTextSpan(textSpan, scriptInfo)
      };
    }
    return {
      definitions: definitions.map(_Session.mapToOriginalLocation),
      textSpan
    };
  }
  findSourceDefinition(args) {
    var _a;
    const { file, project } = this.getFileAndProject(args);
    const position = this.getPositionInFile(args, file);
    const unmappedDefinitions = project.getLanguageService().getDefinitionAtPosition(file, position);
    let definitions = this.mapDefinitionInfoLocations(unmappedDefinitions || emptyArray2, project).slice();
    const needsJsResolution = this.projectService.serverMode === 0 /* Semantic */ && (!some(definitions, (d) => toNormalizedPath(d.fileName) !== file && !d.isAmbient) || some(definitions, (d) => !!d.failedAliasResolution));
    if (needsJsResolution) {
      const definitionSet = createSet(
        (d) => d.textSpan.start,
        getDocumentSpansEqualityComparer(this.host.useCaseSensitiveFileNames)
      );
      definitions == null ? void 0 : definitions.forEach((d) => definitionSet.add(d));
      const noDtsProject = project.getNoDtsResolutionProject(file);
      const ls = noDtsProject.getLanguageService();
      const jsDefinitions = (_a = ls.getDefinitionAtPosition(
        file,
        position,
        /*searchOtherFilesOnly*/
        true,
        /*stopAtAlias*/
        false
      )) == null ? void 0 : _a.filter((d) => toNormalizedPath(d.fileName) !== file);
      if (some(jsDefinitions)) {
        for (const jsDefinition of jsDefinitions) {
          if (jsDefinition.unverified) {
            const refined = tryRefineDefinition(jsDefinition, project.getLanguageService().getProgram(), ls.getProgram());
            if (some(refined)) {
              for (const def of refined) {
                definitionSet.add(def);
              }
              continue;
            }
          }
          definitionSet.add(jsDefinition);
        }
      } else {
        const ambientCandidates = definitions.filter((d) => toNormalizedPath(d.fileName) !== file && d.isAmbient);
        for (const candidate of some(ambientCandidates) ? ambientCandidates : getAmbientCandidatesByClimbingAccessChain()) {
          const fileNameToSearch = findImplementationFileFromDtsFileName(candidate.fileName, file, noDtsProject);
          if (!fileNameToSearch) continue;
          const info = this.projectService.getOrCreateScriptInfoNotOpenedByClient(
            fileNameToSearch,
            noDtsProject.currentDirectory,
            noDtsProject.directoryStructureHost,
            /*deferredDeleteOk*/
            false
          );
          if (!info) continue;
          if (!noDtsProject.containsScriptInfo(info)) {
            noDtsProject.addRoot(info);
            noDtsProject.updateGraph();
          }
          const noDtsProgram = ls.getProgram();
          const fileToSearch = Debug.checkDefined(noDtsProgram.getSourceFile(fileNameToSearch));
          for (const match of searchForDeclaration(candidate.name, fileToSearch, noDtsProgram)) {
            definitionSet.add(match);
          }
        }
      }
      definitions = arrayFrom(definitionSet.values());
    }
    definitions = definitions.filter((d) => !d.isAmbient && !d.failedAliasResolution);
    return this.mapDefinitionInfo(definitions, project);
    function findImplementationFileFromDtsFileName(fileName, resolveFromFile, auxiliaryProject) {
      var _a2, _b, _c;
      const nodeModulesPathParts = getNodeModulePathParts(fileName);
      if (nodeModulesPathParts && fileName.lastIndexOf(nodeModulesPathPart) === nodeModulesPathParts.topLevelNodeModulesIndex) {
        const packageDirectory = fileName.substring(0, nodeModulesPathParts.packageRootIndex);
        const packageJsonCache = (_a2 = project.getModuleResolutionCache()) == null ? void 0 : _a2.getPackageJsonInfoCache();
        const compilerOptions = project.getCompilationSettings();
        const packageJson = getPackageScopeForPath(getNormalizedAbsolutePath(packageDirectory, project.getCurrentDirectory()), getTemporaryModuleResolutionState(packageJsonCache, project, compilerOptions));
        if (!packageJson) return void 0;
        const entrypoints = getEntrypointsFromPackageJsonInfo(
          packageJson,
          { moduleResolution: 2 /* Node10 */ },
          project,
          project.getModuleResolutionCache()
        );
        const packageNamePathPart = fileName.substring(
          nodeModulesPathParts.topLevelPackageNameIndex + 1,
          nodeModulesPathParts.packageRootIndex
        );
        const packageName = getPackageNameFromTypesPackageName(unmangleScopedPackageName(packageNamePathPart));
        const path = project.toPath(fileName);
        if (entrypoints && some(entrypoints, (e) => project.toPath(e) === path)) {
          return (_b = auxiliaryProject.resolutionCache.resolveSingleModuleNameWithoutWatching(packageName, resolveFromFile).resolvedModule) == null ? void 0 : _b.resolvedFileName;
        } else {
          const pathToFileInPackage = fileName.substring(nodeModulesPathParts.packageRootIndex + 1);
          const specifier = `${packageName}/${removeFileExtension(pathToFileInPackage)}`;
          return (_c = auxiliaryProject.resolutionCache.resolveSingleModuleNameWithoutWatching(specifier, resolveFromFile).resolvedModule) == null ? void 0 : _c.resolvedFileName;
        }
      }
      return void 0;
    }
    function getAmbientCandidatesByClimbingAccessChain() {
      const ls = project.getLanguageService();
      const program = ls.getProgram();
      const initialNode = getTouchingPropertyName(program.getSourceFile(file), position);
      if ((isStringLiteralLike(initialNode) || isIdentifier(initialNode)) && isAccessExpression(initialNode.parent)) {
        return forEachNameInAccessChainWalkingLeft(initialNode, (nameInChain) => {
          var _a2;
          if (nameInChain === initialNode) return void 0;
          const candidates = (_a2 = ls.getDefinitionAtPosition(
            file,
            nameInChain.getStart(),
            /*searchOtherFilesOnly*/
            true,
            /*stopAtAlias*/
            false
          )) == null ? void 0 : _a2.filter((d) => toNormalizedPath(d.fileName) !== file && d.isAmbient).map((d) => ({
            fileName: d.fileName,
            name: getTextOfIdentifierOrLiteral(initialNode)
          }));
          if (some(candidates)) {
            return candidates;
          }
        }) || emptyArray2;
      }
      return emptyArray2;
    }
    function tryRefineDefinition(definition, program, noDtsProgram) {
      var _a2;
      const fileToSearch = noDtsProgram.getSourceFile(definition.fileName);
      if (!fileToSearch) {
        return void 0;
      }
      const initialNode = getTouchingPropertyName(program.getSourceFile(file), position);
      const symbol = program.getTypeChecker().getSymbolAtLocation(initialNode);
      const importSpecifier = symbol && getDeclarationOfKind(symbol, 276 /* ImportSpecifier */);
      if (!importSpecifier) return void 0;
      const nameToSearch = ((_a2 = importSpecifier.propertyName) == null ? void 0 : _a2.text) || importSpecifier.name.text;
      return searchForDeclaration(nameToSearch, fileToSearch, noDtsProgram);
    }
    function searchForDeclaration(declarationName, fileToSearch, noDtsProgram) {
      const matches = ts_FindAllReferences_exports.Core.getTopMostDeclarationNamesInFile(declarationName, fileToSearch);
      return mapDefined(matches, (match) => {
        const symbol = noDtsProgram.getTypeChecker().getSymbolAtLocation(match);
        const decl = getDeclarationFromName(match);
        if (symbol && decl) {
          return ts_GoToDefinition_exports.createDefinitionInfo(
            decl,
            noDtsProgram.getTypeChecker(),
            symbol,
            decl,
            /*unverified*/
            true
          );
        }
      });
    }
  }
  getEmitOutput(args) {
    const { file, project } = this.getFileAndProject(args);
    if (!project.shouldEmitFile(project.getScriptInfo(file))) {
      return { emitSkipped: true, outputFiles: [], diagnostics: [] };
    }
    const result = project.getLanguageService().getEmitOutput(file);
    return args.richResponse ? {
      ...result,
      diagnostics: args.includeLinePosition ? this.convertToDiagnosticsWithLinePositionFromDiagnosticFile(result.diagnostics) : result.diagnostics.map((d) => formatDiagnosticToProtocol(
        d,
        /*includeFileName*/
        true
      ))
    } : result;
  }
  mapJSDocTagInfo(tags, project, richResponse) {
    return tags ? tags.map((tag) => {
      var _a;
      return {
        ...tag,
        text: richResponse ? this.mapDisplayParts(tag.text, project) : (_a = tag.text) == null ? void 0 : _a.map((part) => part.text).join("")
      };
    }) : [];
  }
  mapDisplayParts(parts, project) {
    if (!parts) {
      return [];
    }
    return parts.map(
      (part) => part.kind !== "linkName" ? part : {
        ...part,
        target: this.toFileSpan(part.target.fileName, part.target.textSpan, project)
      }
    );
  }
  mapSignatureHelpItems(items, project, richResponse) {
    return items.map((item) => ({
      ...item,
      documentation: this.mapDisplayParts(item.documentation, project),
      parameters: item.parameters.map((p) => ({ ...p, documentation: this.mapDisplayParts(p.documentation, project) })),
      tags: this.mapJSDocTagInfo(item.tags, project, richResponse)
    }));
  }
  mapDefinitionInfo(definitions, project) {
    return definitions.map((def) => ({ ...this.toFileSpanWithContext(def.fileName, def.textSpan, def.contextSpan, project), ...def.unverified && { unverified: def.unverified } }));
  }
  /*
   * When we map a .d.ts location to .ts, Visual Studio gets confused because there's no associated Roslyn Document in
   * the same project which corresponds to the file. VS Code has no problem with this, and luckily we have two protocols.
   * This retains the existing behavior for the "simplified" (VS Code) protocol but stores the .d.ts location in a
   * set of additional fields, and does the reverse for VS (store the .d.ts location where
   * it used to be and stores the .ts location in the additional fields).
   */
  static mapToOriginalLocation(def) {
    if (def.originalFileName) {
      Debug.assert(def.originalTextSpan !== void 0, "originalTextSpan should be present if originalFileName is");
      return {
        ...def,
        fileName: def.originalFileName,
        textSpan: def.originalTextSpan,
        targetFileName: def.fileName,
        targetTextSpan: def.textSpan,
        contextSpan: def.originalContextSpan,
        targetContextSpan: def.contextSpan
      };
    }
    return def;
  }
  toFileSpan(fileName, textSpan, project) {
    const ls = project.getLanguageService();
    const start = ls.toLineColumnOffset(fileName, textSpan.start);
    const end = ls.toLineColumnOffset(fileName, textSpanEnd(textSpan));
    return {
      file: fileName,
      start: { line: start.line + 1, offset: start.character + 1 },
      end: { line: end.line + 1, offset: end.character + 1 }
    };
  }
  toFileSpanWithContext(fileName, textSpan, contextSpan, project) {
    const fileSpan = this.toFileSpan(fileName, textSpan, project);
    const context = contextSpan && this.toFileSpan(fileName, contextSpan, project);
    return context ? { ...fileSpan, contextStart: context.start, contextEnd: context.end } : fileSpan;
  }
  getTypeDefinition(args) {
    const { file, project } = this.getFileAndProject(args);
    const position = this.getPositionInFile(args, file);
    const definitions = this.mapDefinitionInfoLocations(project.getLanguageService().getTypeDefinitionAtPosition(file, position) || emptyArray2, project);
    return this.mapDefinitionInfo(definitions, project);
  }
  mapImplementationLocations(implementations, project) {
    return implementations.map((info) => {
      const newDocumentSpan = getMappedDocumentSpanForProject(info, project);
      return !newDocumentSpan ? info : {
        ...newDocumentSpan,
        kind: info.kind,
        displayParts: info.displayParts
      };
    });
  }
  getImplementation(args, simplifiedResult) {
    const { file, project } = this.getFileAndProject(args);
    const position = this.getPositionInFile(args, file);
    const implementations = this.mapImplementationLocations(project.getLanguageService().getImplementationAtPosition(file, position) || emptyArray2, project);
    return simplifiedResult ? implementations.map(({ fileName, textSpan, contextSpan }) => this.toFileSpanWithContext(fileName, textSpan, contextSpan, project)) : implementations.map(_Session.mapToOriginalLocation);
  }
  getSyntacticDiagnosticsSync(args) {
    const { configFile } = this.getConfigFileAndProject(args);
    if (configFile) {
      return emptyArray2;
    }
    return this.getDiagnosticsWorker(
      args,
      /*isSemantic*/
      false,
      (project, file) => project.getLanguageService().getSyntacticDiagnostics(file),
      !!args.includeLinePosition
    );
  }
  getSemanticDiagnosticsSync(args) {
    const { configFile, project } = this.getConfigFileAndProject(args);
    if (configFile) {
      return this.getConfigFileDiagnostics(configFile, project, !!args.includeLinePosition);
    }
    return this.getDiagnosticsWorker(
      args,
      /*isSemantic*/
      true,
      (project2, file) => project2.getLanguageService().getSemanticDiagnostics(file).filter((d) => !!d.file),
      !!args.includeLinePosition
    );
  }
  getSuggestionDiagnosticsSync(args) {
    const { configFile } = this.getConfigFileAndProject(args);
    if (configFile) {
      return emptyArray2;
    }
    return this.getDiagnosticsWorker(
      args,
      /*isSemantic*/
      true,
      (project, file) => project.getLanguageService().getSuggestionDiagnostics(file),
      !!args.includeLinePosition
    );
  }
  getJsxClosingTag(args) {
    const { file, languageService } = this.getFileAndLanguageServiceForSyntacticOperation(args);
    const position = this.getPositionInFile(args, file);
    const tag = languageService.getJsxClosingTagAtPosition(file, position);
    return tag === void 0 ? void 0 : { newText: tag.newText, caretOffset: 0 };
  }
  getLinkedEditingRange(args) {
    const { file, languageService } = this.getFileAndLanguageServiceForSyntacticOperation(args);
    const position = this.getPositionInFile(args, file);
    const linkedEditInfo = languageService.getLinkedEditingRangeAtPosition(file, position);
    const scriptInfo = this.projectService.getScriptInfoForNormalizedPath(file);
    if (scriptInfo === void 0 || linkedEditInfo === void 0) return void 0;
    return convertLinkedEditInfoToRanges(linkedEditInfo, scriptInfo);
  }
  getDocumentHighlights(args, simplifiedResult) {
    const { file, project } = this.getFileAndProject(args);
    const position = this.getPositionInFile(args, file);
    const documentHighlights = project.getLanguageService().getDocumentHighlights(file, position, args.filesToSearch);
    if (!documentHighlights) return emptyArray2;
    if (!simplifiedResult) return documentHighlights;
    return documentHighlights.map(({ fileName, highlightSpans }) => {
      const scriptInfo = project.getScriptInfo(fileName);
      return {
        file: fileName,
        highlightSpans: highlightSpans.map(({ textSpan, kind, contextSpan }) => ({
          ...toProtocolTextSpanWithContext(textSpan, contextSpan, scriptInfo),
          kind
        }))
      };
    });
  }
  provideInlayHints(args) {
    const { file, project } = this.getFileAndProject(args);
    const scriptInfo = this.projectService.getScriptInfoForNormalizedPath(file);
    const hints = project.getLanguageService().provideInlayHints(file, args, this.getPreferences(file));
    return hints.map((hint) => {
      const { position, displayParts } = hint;
      return {
        ...hint,
        position: scriptInfo.positionToLineOffset(position),
        displayParts: displayParts == null ? void 0 : displayParts.map(({ text, span, file: file2 }) => {
          if (span) {
            Debug.assertIsDefined(file2, "Target file should be defined together with its span.");
            const scriptInfo2 = this.projectService.getScriptInfo(file2);
            return {
              text,
              span: {
                start: scriptInfo2.positionToLineOffset(span.start),
                end: scriptInfo2.positionToLineOffset(span.start + span.length),
                file: file2
              }
            };
          } else {
            return { text };
          }
        })
      };
    });
  }
  mapCode(args) {
    var _a;
    const formatOptions = this.getHostFormatOptions();
    const preferences = this.getHostPreferences();
    const { file, languageService } = this.getFileAndLanguageServiceForSyntacticOperation(args);
    const scriptInfo = this.projectService.getScriptInfoForNormalizedPath(file);
    const focusLocations = (_a = args.mapping.focusLocations) == null ? void 0 : _a.map((spans) => {
      return spans.map((loc) => {
        const start = scriptInfo.lineOffsetToPosition(loc.start.line, loc.start.offset);
        const end = scriptInfo.lineOffsetToPosition(loc.end.line, loc.end.offset);
        return {
          start,
          length: end - start
        };
      });
    });
    const changes = languageService.mapCode(file, args.mapping.contents, focusLocations, formatOptions, preferences);
    return this.mapTextChangesToCodeEdits(changes);
  }
  setCompilerOptionsForInferredProjects(args) {
    this.projectService.setCompilerOptionsForInferredProjects(args.options, args.projectRootPath);
  }
  getProjectInfo(args) {
    return this.getProjectInfoWorker(
      args.file,
      args.projectFileName,
      args.needFileNameList,
      /*excludeConfigFiles*/
      false
    );
  }
  getProjectInfoWorker(uncheckedFileName, projectFileName, needFileNameList, excludeConfigFiles) {
    const { project } = this.getFileAndProjectWorker(uncheckedFileName, projectFileName);
    updateProjectIfDirty(project);
    const projectInfo = {
      configFileName: project.getProjectName(),
      languageServiceDisabled: !project.languageServiceEnabled,
      fileNames: needFileNameList ? project.getFileNames(
        /*excludeFilesFromExternalLibraries*/
        false,
        excludeConfigFiles
      ) : void 0
    };
    return projectInfo;
  }
  getRenameInfo(args) {
    const { file, project } = this.getFileAndProject(args);
    const position = this.getPositionInFile(args, file);
    const preferences = this.getPreferences(file);
    return project.getLanguageService().getRenameInfo(file, position, preferences);
  }
  getProjects(args, getScriptInfoEnsuringProjectsUptoDate, ignoreNoProjectError) {
    let projects;
    let symLinkedProjects;
    if (args.projectFileName) {
      const project = this.getProject(args.projectFileName);
      if (project) {
        projects = [project];
      }
    } else {
      const scriptInfo = getScriptInfoEnsuringProjectsUptoDate ? this.projectService.getScriptInfoEnsuringProjectsUptoDate(args.file) : this.projectService.getScriptInfo(args.file);
      if (!scriptInfo) {
        if (ignoreNoProjectError) return emptyArray2;
        this.projectService.logErrorForScriptInfoNotFound(args.file);
        return Errors.ThrowNoProject();
      } else if (!getScriptInfoEnsuringProjectsUptoDate) {
        this.projectService.ensureDefaultProjectForFile(scriptInfo);
      }
      projects = scriptInfo.containingProjects;
      symLinkedProjects = this.projectService.getSymlinkedProjects(scriptInfo);
    }
    projects = filter(projects, (p) => p.languageServiceEnabled && !p.isOrphan());
    if (!ignoreNoProjectError && (!projects || !projects.length) && !symLinkedProjects) {
      this.projectService.logErrorForScriptInfoNotFound(args.file ?? args.projectFileName);
      return Errors.ThrowNoProject();
    }
    return symLinkedProjects ? { projects, symLinkedProjects } : projects;
  }
  getDefaultProject(args) {
    if (args.projectFileName) {
      const project = this.getProject(args.projectFileName);
      if (project) {
        return project;
      }
      if (!args.file) {
        return Errors.ThrowNoProject();
      }
    }
    const info = this.projectService.getScriptInfo(args.file);
    return info.getDefaultProject();
  }
  getRenameLocations(args, simplifiedResult) {
    const file = toNormalizedPath(args.file);
    const position = this.getPositionInFile(args, file);
    const projects = this.getProjects(args);
    const defaultProject = this.getDefaultProject(args);
    const preferences = this.getPreferences(file);
    const renameInfo = this.mapRenameInfo(
      defaultProject.getLanguageService().getRenameInfo(file, position, preferences),
      Debug.checkDefined(this.projectService.getScriptInfo(file))
    );
    if (!renameInfo.canRename) return simplifiedResult ? { info: renameInfo, locs: [] } : [];
    const locations = getRenameLocationsWorker(
      projects,
      defaultProject,
      { fileName: args.file, pos: position },
      !!args.findInStrings,
      !!args.findInComments,
      preferences,
      this.host.useCaseSensitiveFileNames
    );
    if (!simplifiedResult) return locations;
    return { info: renameInfo, locs: this.toSpanGroups(locations) };
  }
  mapRenameInfo(info, scriptInfo) {
    if (info.canRename) {
      const { canRename, fileToRename, displayName, fullDisplayName, kind, kindModifiers, triggerSpan } = info;
      return identity(
        { canRename, fileToRename, displayName, fullDisplayName, kind, kindModifiers, triggerSpan: toProtocolTextSpan(triggerSpan, scriptInfo) }
      );
    } else {
      return info;
    }
  }
  toSpanGroups(locations) {
    const map2 = /* @__PURE__ */ new Map();
    for (const { fileName, textSpan, contextSpan, originalContextSpan: _2, originalTextSpan: _, originalFileName: _1, ...prefixSuffixText } of locations) {
      let group2 = map2.get(fileName);
      if (!group2) map2.set(fileName, group2 = { file: fileName, locs: [] });
      const scriptInfo = Debug.checkDefined(this.projectService.getScriptInfo(fileName));
      group2.locs.push({ ...toProtocolTextSpanWithContext(textSpan, contextSpan, scriptInfo), ...prefixSuffixText });
    }
    return arrayFrom(map2.values());
  }
  getReferences(args, simplifiedResult) {
    const file = toNormalizedPath(args.file);
    const projects = this.getProjects(args);
    const position = this.getPositionInFile(args, file);
    const references = getReferencesWorker(
      projects,
      this.getDefaultProject(args),
      { fileName: args.file, pos: position },
      this.host.useCaseSensitiveFileNames,
      this.logger
    );
    if (!simplifiedResult) return references;
    const preferences = this.getPreferences(file);
    const defaultProject = this.getDefaultProject(args);
    const scriptInfo = defaultProject.getScriptInfoForNormalizedPath(file);
    const nameInfo = defaultProject.getLanguageService().getQuickInfoAtPosition(file, position);
    const symbolDisplayString = nameInfo ? displayPartsToString(nameInfo.displayParts) : "";
    const nameSpan = nameInfo && nameInfo.textSpan;
    const symbolStartOffset = nameSpan ? scriptInfo.positionToLineOffset(nameSpan.start).offset : 0;
    const symbolName2 = nameSpan ? scriptInfo.getSnapshot().getText(nameSpan.start, textSpanEnd(nameSpan)) : "";
    const refs = flatMap(references, (referencedSymbol) => {
      return referencedSymbol.references.map((entry) => referenceEntryToReferencesResponseItem(this.projectService, entry, preferences));
    });
    return { refs, symbolName: symbolName2, symbolStartOffset, symbolDisplayString };
  }
  getFileReferences(args, simplifiedResult) {
    const projects = this.getProjects(args);
    const fileName = args.file;
    const preferences = this.getPreferences(toNormalizedPath(fileName));
    const references = [];
    const seen = createDocumentSpanSet(this.host.useCaseSensitiveFileNames);
    forEachProjectInProjects(
      projects,
      /*path*/
      void 0,
      (project) => {
        if (project.getCancellationToken().isCancellationRequested()) return;
        const projectOutputs = project.getLanguageService().getFileReferences(fileName);
        if (projectOutputs) {
          for (const referenceEntry of projectOutputs) {
            if (!seen.has(referenceEntry)) {
              references.push(referenceEntry);
              seen.add(referenceEntry);
            }
          }
        }
      }
    );
    if (!simplifiedResult) return references;
    const refs = references.map((entry) => referenceEntryToReferencesResponseItem(this.projectService, entry, preferences));
    return {
      refs,
      symbolName: `"${args.file}"`
    };
  }
  /**
   * @param fileName is the name of the file to be opened
   * @param fileContent is a version of the file content that is known to be more up to date than the one on disk
   */
  openClientFile(fileName, fileContent, scriptKind, projectRootPath) {
    this.projectService.openClientFileWithNormalizedPath(
      fileName,
      fileContent,
      scriptKind,
      /*hasMixedContent*/
      false,
      projectRootPath
    );
  }
  getPosition(args, scriptInfo) {
    return args.position !== void 0 ? args.position : scriptInfo.lineOffsetToPosition(args.line, args.offset);
  }
  getPositionInFile(args, file) {
    const scriptInfo = this.projectService.getScriptInfoForNormalizedPath(file);
    return this.getPosition(args, scriptInfo);
  }
  getFileAndProject(args) {
    return this.getFileAndProjectWorker(args.file, args.projectFileName);
  }
  getFileAndLanguageServiceForSyntacticOperation(args) {
    const { file, project } = this.getFileAndProject(args);
    return {
      file,
      languageService: project.getLanguageService(
        /*ensureSynchronized*/
        false
      )
    };
  }
  getFileAndProjectWorker(uncheckedFileName, projectFileName) {
    const file = toNormalizedPath(uncheckedFileName);
    const project = this.getProject(projectFileName) || this.projectService.ensureDefaultProjectForFile(file);
    return { file, project };
  }
  getOutliningSpans(args, simplifiedResult) {
    const { file, languageService } = this.getFileAndLanguageServiceForSyntacticOperation(args);
    const spans = languageService.getOutliningSpans(file);
    if (simplifiedResult) {
      const scriptInfo = this.projectService.getScriptInfoForNormalizedPath(file);
      return spans.map((s) => ({
        textSpan: toProtocolTextSpan(s.textSpan, scriptInfo),
        hintSpan: toProtocolTextSpan(s.hintSpan, scriptInfo),
        bannerText: s.bannerText,
        autoCollapse: s.autoCollapse,
        kind: s.kind
      }));
    } else {
      return spans;
    }
  }
  getTodoComments(args) {
    const { file, project } = this.getFileAndProject(args);
    return project.getLanguageService().getTodoComments(file, args.descriptors);
  }
  getDocCommentTemplate(args) {
    const { file, languageService } = this.getFileAndLanguageServiceForSyntacticOperation(args);
    const position = this.getPositionInFile(args, file);
    return languageService.getDocCommentTemplateAtPosition(file, position, this.getPreferences(file), this.getFormatOptions(file));
  }
  getSpanOfEnclosingComment(args) {
    const { file, languageService } = this.getFileAndLanguageServiceForSyntacticOperation(args);
    const onlyMultiLine = args.onlyMultiLine;
    const position = this.getPositionInFile(args, file);
    return languageService.getSpanOfEnclosingComment(file, position, onlyMultiLine);
  }
  getIndentation(args) {
    const { file, languageService } = this.getFileAndLanguageServiceForSyntacticOperation(args);
    const position = this.getPositionInFile(args, file);
    const options = args.options ? convertFormatOptions(args.options) : this.getFormatOptions(file);
    const indentation = languageService.getIndentationAtPosition(file, position, options);
    return { position, indentation };
  }
  getBreakpointStatement(args) {
    const { file, languageService } = this.getFileAndLanguageServiceForSyntacticOperation(args);
    const position = this.getPositionInFile(args, file);
    return languageService.getBreakpointStatementAtPosition(file, position);
  }
  getNameOrDottedNameSpan(args) {
    const { file, languageService } = this.getFileAndLanguageServiceForSyntacticOperation(args);
    const position = this.getPositionInFile(args, file);
    return languageService.getNameOrDottedNameSpan(file, position, position);
  }
  isValidBraceCompletion(args) {
    const { file, languageService } = this.getFileAndLanguageServiceForSyntacticOperation(args);
    const position = this.getPositionInFile(args, file);
    return languageService.isValidBraceCompletionAtPosition(file, position, args.openingBrace.charCodeAt(0));
  }
  getQuickInfoWorker(args, simplifiedResult) {
    const { file, project } = this.getFileAndProject(args);
    const scriptInfo = this.projectService.getScriptInfoForNormalizedPath(file);
    const quickInfo = project.getLanguageService().getQuickInfoAtPosition(file, this.getPosition(args, scriptInfo));
    if (!quickInfo) {
      return void 0;
    }
    const useDisplayParts = !!this.getPreferences(file).displayPartsForJSDoc;
    if (simplifiedResult) {
      const displayString = displayPartsToString(quickInfo.displayParts);
      return {
        kind: quickInfo.kind,
        kindModifiers: quickInfo.kindModifiers,
        start: scriptInfo.positionToLineOffset(quickInfo.textSpan.start),
        end: scriptInfo.positionToLineOffset(textSpanEnd(quickInfo.textSpan)),
        displayString,
        documentation: useDisplayParts ? this.mapDisplayParts(quickInfo.documentation, project) : displayPartsToString(quickInfo.documentation),
        tags: this.mapJSDocTagInfo(quickInfo.tags, project, useDisplayParts)
      };
    } else {
      return useDisplayParts ? quickInfo : {
        ...quickInfo,
        tags: this.mapJSDocTagInfo(
          quickInfo.tags,
          project,
          /*richResponse*/
          false
        )
      };
    }
  }
  getFormattingEditsForRange(args) {
    const { file, languageService } = this.getFileAndLanguageServiceForSyntacticOperation(args);
    const scriptInfo = this.projectService.getScriptInfoForNormalizedPath(file);
    const startPosition = scriptInfo.lineOffsetToPosition(args.line, args.offset);
    const endPosition = scriptInfo.lineOffsetToPosition(args.endLine, args.endOffset);
    const edits = languageService.getFormattingEditsForRange(file, startPosition, endPosition, this.getFormatOptions(file));
    if (!edits) {
      return void 0;
    }
    return edits.map((edit) => this.convertTextChangeToCodeEdit(edit, scriptInfo));
  }
  getFormattingEditsForRangeFull(args) {
    const { file, languageService } = this.getFileAndLanguageServiceForSyntacticOperation(args);
    const options = args.options ? convertFormatOptions(args.options) : this.getFormatOptions(file);
    return languageService.getFormattingEditsForRange(file, args.position, args.endPosition, options);
  }
  getFormattingEditsForDocumentFull(args) {
    const { file, languageService } = this.getFileAndLanguageServiceForSyntacticOperation(args);
    const options = args.options ? convertFormatOptions(args.options) : this.getFormatOptions(file);
    return languageService.getFormattingEditsForDocument(file, options);
  }
  getFormattingEditsAfterKeystrokeFull(args) {
    const { file, languageService } = this.getFileAndLanguageServiceForSyntacticOperation(args);
    const options = args.options ? convertFormatOptions(args.options) : this.getFormatOptions(file);
    return languageService.getFormattingEditsAfterKeystroke(file, args.position, args.key, options);
  }
  getFormattingEditsAfterKeystroke(args) {
    const { file, languageService } = this.getFileAndLanguageServiceForSyntacticOperation(args);
    const scriptInfo = this.projectService.getScriptInfoForNormalizedPath(file);
    const position = scriptInfo.lineOffsetToPosition(args.line, args.offset);
    const formatOptions = this.getFormatOptions(file);
    const edits = languageService.getFormattingEditsAfterKeystroke(file, position, args.key, formatOptions);
    if (args.key === "\n" && (!edits || edits.length === 0 || allEditsBeforePos(edits, position))) {
      const { lineText, absolutePosition } = scriptInfo.textStorage.getAbsolutePositionAndLineText(args.line);
      if (lineText && lineText.search("\\S") < 0) {
        const preferredIndent = languageService.getIndentationAtPosition(file, position, formatOptions);
        let hasIndent = 0;
        let i, len;
        for (i = 0, len = lineText.length; i < len; i++) {
          if (lineText.charAt(i) === " ") {
            hasIndent++;
          } else if (lineText.charAt(i) === "	") {
            hasIndent += formatOptions.tabSize;
          } else {
            break;
          }
        }
        if (preferredIndent !== hasIndent) {
          const firstNoWhiteSpacePosition = absolutePosition + i;
          edits.push({
            span: createTextSpanFromBounds(absolutePosition, firstNoWhiteSpacePosition),
            newText: ts_formatting_exports.getIndentationString(preferredIndent, formatOptions)
          });
        }
      }
    }
    if (!edits) {
      return void 0;
    }
    return edits.map((edit) => {
      return {
        start: scriptInfo.positionToLineOffset(edit.span.start),
        end: scriptInfo.positionToLineOffset(textSpanEnd(edit.span)),
        newText: edit.newText ? edit.newText : ""
      };
    });
  }
  getCompletions(args, kind) {
    const { file, project } = this.getFileAndProject(args);
    const scriptInfo = this.projectService.getScriptInfoForNormalizedPath(file);
    const position = this.getPosition(args, scriptInfo);
    const completions = project.getLanguageService().getCompletionsAtPosition(
      file,
      position,
      {
        ...convertUserPreferences(this.getPreferences(file)),
        triggerCharacter: args.triggerCharacter,
        triggerKind: args.triggerKind,
        includeExternalModuleExports: args.includeExternalModuleExports,
        includeInsertTextCompletions: args.includeInsertTextCompletions
      },
      project.projectService.getFormatCodeOptions(file)
    );
    if (completions === void 0) return void 0;
    if (kind === "completions-full" /* CompletionsFull */) return completions;
    const prefix = args.prefix || "";
    const entries = mapDefined(completions.entries, (entry) => {
      if (completions.isMemberCompletion || startsWith(entry.name.toLowerCase(), prefix.toLowerCase())) {
        const convertedSpan = entry.replacementSpan ? toProtocolTextSpan(entry.replacementSpan, scriptInfo) : void 0;
        return {
          ...entry,
          replacementSpan: convertedSpan,
          hasAction: entry.hasAction || void 0,
          symbol: void 0
        };
      }
    });
    if (kind === "completions" /* Completions */) {
      if (completions.metadata) entries.metadata = completions.metadata;
      return entries;
    }
    const res = {
      ...completions,
      optionalReplacementSpan: completions.optionalReplacementSpan && toProtocolTextSpan(completions.optionalReplacementSpan, scriptInfo),
      entries
    };
    return res;
  }
  getCompletionEntryDetails(args, fullResult) {
    const { file, project } = this.getFileAndProject(args);
    const scriptInfo = this.projectService.getScriptInfoForNormalizedPath(file);
    const position = this.getPosition(args, scriptInfo);
    const formattingOptions = project.projectService.getFormatCodeOptions(file);
    const useDisplayParts = !!this.getPreferences(file).displayPartsForJSDoc;
    const result = mapDefined(args.entryNames, (entryName) => {
      const { name, source, data } = typeof entryName === "string" ? { name: entryName, source: void 0, data: void 0 } : entryName;
      return project.getLanguageService().getCompletionEntryDetails(file, position, name, formattingOptions, source, this.getPreferences(file), data ? cast(data, isCompletionEntryData) : void 0);
    });
    return fullResult ? useDisplayParts ? result : result.map((details) => ({ ...details, tags: this.mapJSDocTagInfo(
      details.tags,
      project,
      /*richResponse*/
      false
    ) })) : result.map((details) => ({
      ...details,
      codeActions: map(details.codeActions, (action) => this.mapCodeAction(action)),
      documentation: this.mapDisplayParts(details.documentation, project),
      tags: this.mapJSDocTagInfo(details.tags, project, useDisplayParts)
    }));
  }
  getCompileOnSaveAffectedFileList(args) {
    const projects = this.getProjects(
      args,
      /*getScriptInfoEnsuringProjectsUptoDate*/
      true,
      /*ignoreNoProjectError*/
      true
    );
    const info = this.projectService.getScriptInfo(args.file);
    if (!info) {
      return emptyArray2;
    }
    return combineProjectOutput(
      info,
      (path) => this.projectService.getScriptInfoForPath(path),
      projects,
      (project, info2) => {
        if (!project.compileOnSaveEnabled || !project.languageServiceEnabled || project.isOrphan()) {
          return void 0;
        }
        const compilationSettings = project.getCompilationSettings();
        if (!!compilationSettings.noEmit || isDeclarationFileName(info2.fileName) && !dtsChangeCanAffectEmit(compilationSettings)) {
          return void 0;
        }
        return {
          projectFileName: project.getProjectName(),
          fileNames: project.getCompileOnSaveAffectedFileList(info2),
          projectUsesOutFile: !!compilationSettings.outFile
        };
      }
    );
  }
  emitFile(args) {
    const { file, project } = this.getFileAndProject(args);
    if (!project) {
      Errors.ThrowNoProject();
    }
    if (!project.languageServiceEnabled) {
      return args.richResponse ? { emitSkipped: true, diagnostics: [] } : false;
    }
    const scriptInfo = project.getScriptInfo(file);
    const { emitSkipped, diagnostics } = project.emitFile(scriptInfo, (path, data, writeByteOrderMark) => this.host.writeFile(path, data, writeByteOrderMark));
    return args.richResponse ? {
      emitSkipped,
      diagnostics: args.includeLinePosition ? this.convertToDiagnosticsWithLinePositionFromDiagnosticFile(diagnostics) : diagnostics.map((d) => formatDiagnosticToProtocol(
        d,
        /*includeFileName*/
        true
      ))
    } : !emitSkipped;
  }
  getSignatureHelpItems(args, simplifiedResult) {
    const { file, project } = this.getFileAndProject(args);
    const scriptInfo = this.projectService.getScriptInfoForNormalizedPath(file);
    const position = this.getPosition(args, scriptInfo);
    const helpItems = project.getLanguageService().getSignatureHelpItems(file, position, args);
    const useDisplayParts = !!this.getPreferences(file).displayPartsForJSDoc;
    if (helpItems && simplifiedResult) {
      const span = helpItems.applicableSpan;
      return {
        ...helpItems,
        applicableSpan: {
          start: scriptInfo.positionToLineOffset(span.start),
          end: scriptInfo.positionToLineOffset(span.start + span.length)
        },
        items: this.mapSignatureHelpItems(helpItems.items, project, useDisplayParts)
      };
    } else if (useDisplayParts || !helpItems) {
      return helpItems;
    } else {
      return {
        ...helpItems,
        items: helpItems.items.map((item) => ({ ...item, tags: this.mapJSDocTagInfo(
          item.tags,
          project,
          /*richResponse*/
          false
        ) }))
      };
    }
  }
  toPendingErrorCheck(uncheckedFileName) {
    const fileName = toNormalizedPath(uncheckedFileName);
    const project = this.projectService.tryGetDefaultProjectForFile(fileName);
    return project && { fileName, project };
  }
  getDiagnostics(next, delay, fileArgs) {
    if (this.suppressDiagnosticEvents) {
      return;
    }
    if (fileArgs.length > 0) {
      this.updateErrorCheck(next, fileArgs, delay);
    }
  }
  change(args) {
    const scriptInfo = this.projectService.getScriptInfo(args.file);
    Debug.assert(!!scriptInfo);
    scriptInfo.textStorage.switchToScriptVersionCache();
    const start = scriptInfo.lineOffsetToPosition(args.line, args.offset);
    const end = scriptInfo.lineOffsetToPosition(args.endLine, args.endOffset);
    if (start >= 0) {
      this.changeSeq++;
      this.projectService.applyChangesToFile(
        scriptInfo,
        singleIterator({
          span: { start, length: end - start },
          newText: args.insertString
          // TODO: GH#18217
        })
      );
    }
  }
  reload(args) {
    const file = toNormalizedPath(args.file);
    const tempFileName = args.tmpfile === void 0 ? void 0 : toNormalizedPath(args.tmpfile);
    const info = this.projectService.getScriptInfoForNormalizedPath(file);
    if (info) {
      this.changeSeq++;
      info.reloadFromFile(tempFileName);
    }
  }
  saveToTmp(fileName, tempFileName) {
    const scriptInfo = this.projectService.getScriptInfo(fileName);
    if (scriptInfo) {
      scriptInfo.saveTo(tempFileName);
    }
  }
  closeClientFile(fileName) {
    if (!fileName) {
      return;
    }
    const file = normalizePath(fileName);
    this.projectService.closeClientFile(file);
  }
  mapLocationNavigationBarItems(items, scriptInfo) {
    return map(items, (item) => ({
      text: item.text,
      kind: item.kind,
      kindModifiers: item.kindModifiers,
      spans: item.spans.map((span) => toProtocolTextSpan(span, scriptInfo)),
      childItems: this.mapLocationNavigationBarItems(item.childItems, scriptInfo),
      indent: item.indent
    }));
  }
  getNavigationBarItems(args, simplifiedResult) {
    const { file, languageService } = this.getFileAndLanguageServiceForSyntacticOperation(args);
    const items = languageService.getNavigationBarItems(file);
    return !items ? void 0 : simplifiedResult ? this.mapLocationNavigationBarItems(items, this.projectService.getScriptInfoForNormalizedPath(file)) : items;
  }
  toLocationNavigationTree(tree, scriptInfo) {
    return {
      text: tree.text,
      kind: tree.kind,
      kindModifiers: tree.kindModifiers,
      spans: tree.spans.map((span) => toProtocolTextSpan(span, scriptInfo)),
      nameSpan: tree.nameSpan && toProtocolTextSpan(tree.nameSpan, scriptInfo),
      childItems: map(tree.childItems, (item) => this.toLocationNavigationTree(item, scriptInfo))
    };
  }
  getNavigationTree(args, simplifiedResult) {
    const { file, languageService } = this.getFileAndLanguageServiceForSyntacticOperation(args);
    const tree = languageService.getNavigationTree(file);
    return !tree ? void 0 : simplifiedResult ? this.toLocationNavigationTree(tree, this.projectService.getScriptInfoForNormalizedPath(file)) : tree;
  }
  getNavigateToItems(args, simplifiedResult) {
    const full = this.getFullNavigateToItems(args);
    return !simplifiedResult ? flatMap(full, ({ navigateToItems }) => navigateToItems) : flatMap(
      full,
      ({ project, navigateToItems }) => navigateToItems.map((navItem) => {
        const scriptInfo = project.getScriptInfo(navItem.fileName);
        const bakedItem = {
          name: navItem.name,
          kind: navItem.kind,
          kindModifiers: navItem.kindModifiers,
          isCaseSensitive: navItem.isCaseSensitive,
          matchKind: navItem.matchKind,
          file: navItem.fileName,
          start: scriptInfo.positionToLineOffset(navItem.textSpan.start),
          end: scriptInfo.positionToLineOffset(textSpanEnd(navItem.textSpan))
        };
        if (navItem.kindModifiers && navItem.kindModifiers !== "") {
          bakedItem.kindModifiers = navItem.kindModifiers;
        }
        if (navItem.containerName && navItem.containerName.length > 0) {
          bakedItem.containerName = navItem.containerName;
        }
        if (navItem.containerKind && navItem.containerKind.length > 0) {
          bakedItem.containerKind = navItem.containerKind;
        }
        return bakedItem;
      })
    );
  }
  getFullNavigateToItems(args) {
    const { currentFileOnly, searchValue, maxResultCount, projectFileName } = args;
    if (currentFileOnly) {
      Debug.assertIsDefined(args.file);
      const { file, project } = this.getFileAndProject(args);
      return [{ project, navigateToItems: project.getLanguageService().getNavigateToItems(searchValue, maxResultCount, file) }];
    }
    const preferences = this.getHostPreferences();
    const outputs = [];
    const seenItems = /* @__PURE__ */ new Map();
    if (!args.file && !projectFileName) {
      this.projectService.loadAncestorProjectTree();
      this.projectService.forEachEnabledProject((project) => addItemsForProject(project));
    } else {
      const projects = this.getProjects(args);
      forEachProjectInProjects(
        projects,
        /*path*/
        void 0,
        (project) => addItemsForProject(project)
      );
    }
    return outputs;
    function addItemsForProject(project) {
      const projectItems = project.getLanguageService().getNavigateToItems(
        searchValue,
        maxResultCount,
        /*fileName*/
        void 0,
        /*excludeDts*/
        project.isNonTsProject(),
        /*excludeLibFiles*/
        preferences.excludeLibrarySymbolsInNavTo
      );
      const unseenItems = filter(projectItems, (item) => tryAddSeenItem(item) && !getMappedLocationForProject(documentSpanLocation(item), project));
      if (unseenItems.length) {
        outputs.push({ project, navigateToItems: unseenItems });
      }
    }
    function tryAddSeenItem(item) {
      const name = item.name;
      if (!seenItems.has(name)) {
        seenItems.set(name, [item]);
        return true;
      }
      const seen = seenItems.get(name);
      for (const seenItem of seen) {
        if (navigateToItemIsEqualTo(seenItem, item)) {
          return false;
        }
      }
      seen.push(item);
      return true;
    }
    function navigateToItemIsEqualTo(a, b) {
      if (a === b) {
        return true;
      }
      if (!a || !b) {
        return false;
      }
      return a.containerKind === b.containerKind && a.containerName === b.containerName && a.fileName === b.fileName && a.isCaseSensitive === b.isCaseSensitive && a.kind === b.kind && a.kindModifiers === b.kindModifiers && a.matchKind === b.matchKind && a.name === b.name && a.textSpan.start === b.textSpan.start && a.textSpan.length === b.textSpan.length;
    }
  }
  getSupportedCodeFixes(args) {
    if (!args) return getSupportedCodeFixes();
    if (args.file) {
      const { file, project: project2 } = this.getFileAndProject(args);
      return project2.getLanguageService().getSupportedCodeFixes(file);
    }
    const project = this.getProject(args.projectFileName);
    if (!project) Errors.ThrowNoProject();
    return project.getLanguageService().getSupportedCodeFixes();
  }
  isLocation(locationOrSpan) {
    return locationOrSpan.line !== void 0;
  }
  extractPositionOrRange(args, scriptInfo) {
    let position;
    let textRange;
    if (this.isLocation(args)) {
      position = getPosition(args);
    } else {
      textRange = this.getRange(args, scriptInfo);
    }
    return Debug.checkDefined(position === void 0 ? textRange : position);
    function getPosition(loc) {
      return loc.position !== void 0 ? loc.position : scriptInfo.lineOffsetToPosition(loc.line, loc.offset);
    }
  }
  getRange(args, scriptInfo) {
    const { startPosition, endPosition } = this.getStartAndEndPosition(args, scriptInfo);
    return { pos: startPosition, end: endPosition };
  }
  getApplicableRefactors(args) {
    const { file, project } = this.getFileAndProject(args);
    const scriptInfo = project.getScriptInfoForNormalizedPath(file);
    const result = project.getLanguageService().getApplicableRefactors(file, this.extractPositionOrRange(args, scriptInfo), this.getPreferences(file), args.triggerReason, args.kind, args.includeInteractiveActions);
    return result.map((result2) => ({ ...result2, actions: result2.actions.map((action) => ({ ...action, range: action.range ? { start: convertToLocation({ line: action.range.start.line, character: action.range.start.offset }), end: convertToLocation({ line: action.range.end.line, character: action.range.end.offset }) } : void 0 })) }));
  }
  getEditsForRefactor(args, simplifiedResult) {
    const { file, project } = this.getFileAndProject(args);
    const scriptInfo = project.getScriptInfoForNormalizedPath(file);
    const result = project.getLanguageService().getEditsForRefactor(
      file,
      this.getFormatOptions(file),
      this.extractPositionOrRange(args, scriptInfo),
      args.refactor,
      args.action,
      this.getPreferences(file),
      args.interactiveRefactorArguments
    );
    if (result === void 0) {
      return {
        edits: []
      };
    }
    if (simplifiedResult) {
      const { renameFilename, renameLocation, edits } = result;
      let mappedRenameLocation;
      if (renameFilename !== void 0 && renameLocation !== void 0) {
        const renameScriptInfo = project.getScriptInfoForNormalizedPath(toNormalizedPath(renameFilename));
        mappedRenameLocation = getLocationInNewDocument(getSnapshotText(renameScriptInfo.getSnapshot()), renameFilename, renameLocation, edits);
      }
      return {
        renameLocation: mappedRenameLocation,
        renameFilename,
        edits: this.mapTextChangesToCodeEdits(edits),
        notApplicableReason: result.notApplicableReason
      };
    }
    return result;
  }
  getMoveToRefactoringFileSuggestions(args) {
    const { file, project } = this.getFileAndProject(args);
    const scriptInfo = project.getScriptInfoForNormalizedPath(file);
    return project.getLanguageService().getMoveToRefactoringFileSuggestions(file, this.extractPositionOrRange(args, scriptInfo), this.getPreferences(file));
  }
  getPasteEdits(args) {
    const { file, project } = this.getFileAndProject(args);
    const copiedFrom = args.copiedFrom ? { file: args.copiedFrom.file, range: args.copiedFrom.spans.map((copies) => this.getRange({ file: args.copiedFrom.file, startLine: copies.start.line, startOffset: copies.start.offset, endLine: copies.end.line, endOffset: copies.end.offset }, project.getScriptInfoForNormalizedPath(toNormalizedPath(args.copiedFrom.file)))) } : void 0;
    const result = project.getLanguageService().getPasteEdits(
      {
        targetFile: file,
        pastedText: args.pastedText,
        pasteLocations: args.pasteLocations.map((paste) => this.getRange({ file, startLine: paste.start.line, startOffset: paste.start.offset, endLine: paste.end.line, endOffset: paste.end.offset }, project.getScriptInfoForNormalizedPath(file))),
        copiedFrom,
        preferences: this.getPreferences(file)
      },
      this.getFormatOptions(file)
    );
    return result && this.mapPasteEditsAction(result);
  }
  organizeImports(args, simplifiedResult) {
    Debug.assert(args.scope.type === "file");
    const { file, project } = this.getFileAndProject(args.scope.args);
    const changes = project.getLanguageService().organizeImports(
      {
        fileName: file,
        mode: args.mode ?? (args.skipDestructiveCodeActions ? "SortAndCombine" /* SortAndCombine */ : void 0),
        type: "file"
      },
      this.getFormatOptions(file),
      this.getPreferences(file)
    );
    if (simplifiedResult) {
      return this.mapTextChangesToCodeEdits(changes);
    } else {
      return changes;
    }
  }
  getEditsForFileRename(args, simplifiedResult) {
    const oldPath = toNormalizedPath(args.oldFilePath);
    const newPath = toNormalizedPath(args.newFilePath);
    const formatOptions = this.getHostFormatOptions();
    const preferences = this.getHostPreferences();
    const seenFiles = /* @__PURE__ */ new Set();
    const textChanges2 = [];
    this.projectService.loadAncestorProjectTree();
    this.projectService.forEachEnabledProject((project) => {
      const projectTextChanges = project.getLanguageService().getEditsForFileRename(oldPath, newPath, formatOptions, preferences);
      const projectFiles = [];
      for (const textChange of projectTextChanges) {
        if (!seenFiles.has(textChange.fileName)) {
          textChanges2.push(textChange);
          projectFiles.push(textChange.fileName);
        }
      }
      for (const file of projectFiles) {
        seenFiles.add(file);
      }
    });
    return simplifiedResult ? textChanges2.map((c) => this.mapTextChangeToCodeEdit(c)) : textChanges2;
  }
  getCodeFixes(args, simplifiedResult) {
    const { file, project } = this.getFileAndProject(args);
    const scriptInfo = project.getScriptInfoForNormalizedPath(file);
    const { startPosition, endPosition } = this.getStartAndEndPosition(args, scriptInfo);
    let codeActions;
    try {
      codeActions = project.getLanguageService().getCodeFixesAtPosition(file, startPosition, endPosition, args.errorCodes, this.getFormatOptions(file), this.getPreferences(file));
    } catch (e) {
      const ls = project.getLanguageService();
      const existingDiagCodes = [
        ...ls.getSyntacticDiagnostics(file),
        ...ls.getSemanticDiagnostics(file),
        ...ls.getSuggestionDiagnostics(file)
      ].map(
        (d) => decodedTextSpanIntersectsWith(startPosition, endPosition - startPosition, d.start, d.length) && d.code
      );
      const badCode = args.errorCodes.find((c) => !existingDiagCodes.includes(c));
      if (badCode !== void 0) {
        e.message = `BADCLIENT: Bad error code, ${badCode} not found in range ${startPosition}..${endPosition} (found: ${existingDiagCodes.join(", ")}); could have caused this error:
${e.message}`;
      }
      throw e;
    }
    return simplifiedResult ? codeActions.map((codeAction) => this.mapCodeFixAction(codeAction)) : codeActions;
  }
  getCombinedCodeFix({ scope, fixId: fixId55 }, simplifiedResult) {
    Debug.assert(scope.type === "file");
    const { file, project } = this.getFileAndProject(scope.args);
    const res = project.getLanguageService().getCombinedCodeFix({ type: "file", fileName: file }, fixId55, this.getFormatOptions(file), this.getPreferences(file));
    if (simplifiedResult) {
      return { changes: this.mapTextChangesToCodeEdits(res.changes), commands: res.commands };
    } else {
      return res;
    }
  }
  applyCodeActionCommand(args) {
    const commands = args.command;
    for (const command of toArray(commands)) {
      const { file, project } = this.getFileAndProject(command);
      project.getLanguageService().applyCodeActionCommand(command, this.getFormatOptions(file)).then(
        (_result) => {
        },
        (_error) => {
        }
      );
    }
    return {};
  }
  getStartAndEndPosition(args, scriptInfo) {
    let startPosition, endPosition;
    if (args.startPosition !== void 0) {
      startPosition = args.startPosition;
    } else {
      startPosition = scriptInfo.lineOffsetToPosition(args.startLine, args.startOffset);
      args.startPosition = startPosition;
    }
    if (args.endPosition !== void 0) {
      endPosition = args.endPosition;
    } else {
      endPosition = scriptInfo.lineOffsetToPosition(args.endLine, args.endOffset);
      args.endPosition = endPosition;
    }
    return { startPosition, endPosition };
  }
  mapCodeAction({ description: description3, changes, commands }) {
    return { description: description3, changes: this.mapTextChangesToCodeEdits(changes), commands };
  }
  mapCodeFixAction({ fixName: fixName8, description: description3, changes, commands, fixId: fixId55, fixAllDescription }) {
    return { fixName: fixName8, description: description3, changes: this.mapTextChangesToCodeEdits(changes), commands, fixId: fixId55, fixAllDescription };
  }
  mapPasteEditsAction({ edits, fixId: fixId55 }) {
    return { edits: this.mapTextChangesToCodeEdits(edits), fixId: fixId55 };
  }
  mapTextChangesToCodeEdits(textChanges2) {
    return textChanges2.map((change) => this.mapTextChangeToCodeEdit(change));
  }
  mapTextChangeToCodeEdit(textChanges2) {
    const scriptInfo = this.projectService.getScriptInfoOrConfig(textChanges2.fileName);
    if (!!textChanges2.isNewFile === !!scriptInfo) {
      if (!scriptInfo) {
        this.projectService.logErrorForScriptInfoNotFound(textChanges2.fileName);
      }
      Debug.fail("Expected isNewFile for (only) new files. " + JSON.stringify({ isNewFile: !!textChanges2.isNewFile, hasScriptInfo: !!scriptInfo }));
    }
    return scriptInfo ? { fileName: textChanges2.fileName, textChanges: textChanges2.textChanges.map((textChange) => convertTextChangeToCodeEdit(textChange, scriptInfo)) } : convertNewFileTextChangeToCodeEdit(textChanges2);
  }
  convertTextChangeToCodeEdit(change, scriptInfo) {
    return {
      start: scriptInfo.positionToLineOffset(change.span.start),
      end: scriptInfo.positionToLineOffset(change.span.start + change.span.length),
      newText: change.newText ? change.newText : ""
    };
  }
  getBraceMatching(args, simplifiedResult) {
    const { file, languageService } = this.getFileAndLanguageServiceForSyntacticOperation(args);
    const scriptInfo = this.projectService.getScriptInfoForNormalizedPath(file);
    const position = this.getPosition(args, scriptInfo);
    const spans = languageService.getBraceMatchingAtPosition(file, position);
    return !spans ? void 0 : simplifiedResult ? spans.map((span) => toProtocolTextSpan(span, scriptInfo)) : spans;
  }
  getDiagnosticsForProject(next, delay, fileName) {
    if (this.suppressDiagnosticEvents) {
      return;
    }
    const { fileNames, languageServiceDisabled } = this.getProjectInfoWorker(
      fileName,
      /*projectFileName*/
      void 0,
      /*needFileNameList*/
      true,
      /*excludeConfigFiles*/
      true
    );
    if (languageServiceDisabled) {
      return;
    }
    const fileNamesInProject = fileNames.filter((value) => !value.includes("lib.d.ts"));
    if (fileNamesInProject.length === 0) {
      return;
    }
    const highPriorityFiles = [];
    const mediumPriorityFiles = [];
    const lowPriorityFiles = [];
    const veryLowPriorityFiles = [];
    const normalizedFileName = toNormalizedPath(fileName);
    const project = this.projectService.ensureDefaultProjectForFile(normalizedFileName);
    for (const fileNameInProject of fileNamesInProject) {
      if (this.getCanonicalFileName(fileNameInProject) === this.getCanonicalFileName(fileName)) {
        highPriorityFiles.push(fileNameInProject);
      } else {
        const info = this.projectService.getScriptInfo(fileNameInProject);
        if (!info.isScriptOpen()) {
          if (isDeclarationFileName(fileNameInProject)) {
            veryLowPriorityFiles.push(fileNameInProject);
          } else {
            lowPriorityFiles.push(fileNameInProject);
          }
        } else {
          mediumPriorityFiles.push(fileNameInProject);
        }
      }
    }
    const sortedFiles = [...highPriorityFiles, ...mediumPriorityFiles, ...lowPriorityFiles, ...veryLowPriorityFiles];
    const checkList = sortedFiles.map((fileName2) => ({ fileName: fileName2, project }));
    this.updateErrorCheck(
      next,
      checkList,
      delay,
      /*requireOpen*/
      false
    );
  }
  configurePlugin(args) {
    this.projectService.configurePlugin(args);
  }
  getSmartSelectionRange(args, simplifiedResult) {
    const { locations } = args;
    const { file, languageService } = this.getFileAndLanguageServiceForSyntacticOperation(args);
    const scriptInfo = Debug.checkDefined(this.projectService.getScriptInfo(file));
    return map(locations, (location) => {
      const pos = this.getPosition(location, scriptInfo);
      const selectionRange = languageService.getSmartSelectionRange(file, pos);
      return simplifiedResult ? this.mapSelectionRange(selectionRange, scriptInfo) : selectionRange;
    });
  }
  toggleLineComment(args, simplifiedResult) {
    const { file, languageService } = this.getFileAndLanguageServiceForSyntacticOperation(args);
    const scriptInfo = this.projectService.getScriptInfo(file);
    const textRange = this.getRange(args, scriptInfo);
    const textChanges2 = languageService.toggleLineComment(file, textRange);
    if (simplifiedResult) {
      const scriptInfo2 = this.projectService.getScriptInfoForNormalizedPath(file);
      return textChanges2.map((textChange) => this.convertTextChangeToCodeEdit(textChange, scriptInfo2));
    }
    return textChanges2;
  }
  toggleMultilineComment(args, simplifiedResult) {
    const { file, languageService } = this.getFileAndLanguageServiceForSyntacticOperation(args);
    const scriptInfo = this.projectService.getScriptInfoForNormalizedPath(file);
    const textRange = this.getRange(args, scriptInfo);
    const textChanges2 = languageService.toggleMultilineComment(file, textRange);
    if (simplifiedResult) {
      const scriptInfo2 = this.projectService.getScriptInfoForNormalizedPath(file);
      return textChanges2.map((textChange) => this.convertTextChangeToCodeEdit(textChange, scriptInfo2));
    }
    return textChanges2;
  }
  commentSelection(args, simplifiedResult) {
    const { file, languageService } = this.getFileAndLanguageServiceForSyntacticOperation(args);
    const scriptInfo = this.projectService.getScriptInfoForNormalizedPath(file);
    const textRange = this.getRange(args, scriptInfo);
    const textChanges2 = languageService.commentSelection(file, textRange);
    if (simplifiedResult) {
      const scriptInfo2 = this.projectService.getScriptInfoForNormalizedPath(file);
      return textChanges2.map((textChange) => this.convertTextChangeToCodeEdit(textChange, scriptInfo2));
    }
    return textChanges2;
  }
  uncommentSelection(args, simplifiedResult) {
    const { file, languageService } = this.getFileAndLanguageServiceForSyntacticOperation(args);
    const scriptInfo = this.projectService.getScriptInfoForNormalizedPath(file);
    const textRange = this.getRange(args, scriptInfo);
    const textChanges2 = languageService.uncommentSelection(file, textRange);
    if (simplifiedResult) {
      const scriptInfo2 = this.projectService.getScriptInfoForNormalizedPath(file);
      return textChanges2.map((textChange) => this.convertTextChangeToCodeEdit(textChange, scriptInfo2));
    }
    return textChanges2;
  }
  mapSelectionRange(selectionRange, scriptInfo) {
    const result = {
      textSpan: toProtocolTextSpan(selectionRange.textSpan, scriptInfo)
    };
    if (selectionRange.parent) {
      result.parent = this.mapSelectionRange(selectionRange.parent, scriptInfo);
    }
    return result;
  }
  getScriptInfoFromProjectService(file) {
    const normalizedFile = toNormalizedPath(file);
    const scriptInfo = this.projectService.getScriptInfoForNormalizedPath(normalizedFile);
    if (!scriptInfo) {
      this.projectService.logErrorForScriptInfoNotFound(normalizedFile);
      return Errors.ThrowNoProject();
    }
    return scriptInfo;
  }
  toProtocolCallHierarchyItem(item) {
    const scriptInfo = this.getScriptInfoFromProjectService(item.file);
    return {
      name: item.name,
      kind: item.kind,
      kindModifiers: item.kindModifiers,
      file: item.file,
      containerName: item.containerName,
      span: toProtocolTextSpan(item.span, scriptInfo),
      selectionSpan: toProtocolTextSpan(item.selectionSpan, scriptInfo)
    };
  }
  toProtocolCallHierarchyIncomingCall(incomingCall) {
    const scriptInfo = this.getScriptInfoFromProjectService(incomingCall.from.file);
    return {
      from: this.toProtocolCallHierarchyItem(incomingCall.from),
      fromSpans: incomingCall.fromSpans.map((fromSpan) => toProtocolTextSpan(fromSpan, scriptInfo))
    };
  }
  toProtocolCallHierarchyOutgoingCall(outgoingCall, scriptInfo) {
    return {
      to: this.toProtocolCallHierarchyItem(outgoingCall.to),
      fromSpans: outgoingCall.fromSpans.map((fromSpan) => toProtocolTextSpan(fromSpan, scriptInfo))
    };
  }
  prepareCallHierarchy(args) {
    const { file, project } = this.getFileAndProject(args);
    const scriptInfo = this.projectService.getScriptInfoForNormalizedPath(file);
    if (scriptInfo) {
      const position = this.getPosition(args, scriptInfo);
      const result = project.getLanguageService().prepareCallHierarchy(file, position);
      return result && mapOneOrMany(result, (item) => this.toProtocolCallHierarchyItem(item));
    }
    return void 0;
  }
  provideCallHierarchyIncomingCalls(args) {
    const { file, project } = this.getFileAndProject(args);
    const scriptInfo = this.getScriptInfoFromProjectService(file);
    const incomingCalls = project.getLanguageService().provideCallHierarchyIncomingCalls(file, this.getPosition(args, scriptInfo));
    return incomingCalls.map((call) => this.toProtocolCallHierarchyIncomingCall(call));
  }
  provideCallHierarchyOutgoingCalls(args) {
    const { file, project } = this.getFileAndProject(args);
    const scriptInfo = this.getScriptInfoFromProjectService(file);
    const outgoingCalls = project.getLanguageService().provideCallHierarchyOutgoingCalls(file, this.getPosition(args, scriptInfo));
    return outgoingCalls.map((call) => this.toProtocolCallHierarchyOutgoingCall(call, scriptInfo));
  }
  getCanonicalFileName(fileName) {
    const name = this.host.useCaseSensitiveFileNames ? fileName : toFileNameLowerCase(fileName);
    return normalizePath(name);
  }
  exit() {
  }
  notRequired(request) {
    if (request) this.doOutput(
      /*info*/
      void 0,
      request.command,
      request.seq,
      /*success*/
      true,
      this.performanceData
    );
    return { responseRequired: false, performanceData: this.performanceData };
  }
  requiredResponse(response) {
    return { response, responseRequired: true, performanceData: this.performanceData };
  }
  addProtocolHandler(command, handler) {
    if (this.handlers.has(command)) {
      throw new Error(`Protocol handler already exists for command "${command}"`);
    }
    this.handlers.set(command, handler);
  }
  setCurrentRequest(requestId) {
    Debug.assert(this.currentRequestId === void 0);
    this.currentRequestId = requestId;
    this.cancellationToken.setRequest(requestId);
  }
  resetCurrentRequest(requestId) {
    Debug.assert(this.currentRequestId === requestId);
    this.currentRequestId = void 0;
    this.cancellationToken.resetRequest(requestId);
  }
  // eslint-disable-line @typescript-eslint/unified-signatures
  executeWithRequestId(requestId, f, perfomanceData) {
    const currentPerformanceData = this.performanceData;
    try {
      this.performanceData = perfomanceData;
      this.setCurrentRequest(requestId);
      return f();
    } finally {
      this.resetCurrentRequest(requestId);
      this.performanceData = currentPerformanceData;
    }
  }
  executeCommand(request) {
    const handler = this.handlers.get(request.command);
    if (handler) {
      const response = this.executeWithRequestId(
        request.seq,
        () => handler(request),
        /*perfomanceData*/
        void 0
      );
      this.projectService.enableRequestedPlugins();
      return response;
    } else {
      this.logger.msg(`Unrecognized JSON command:${stringifyIndented(request)}`, "Err" /* Err */);
      this.doOutput(
        /*info*/
        void 0,
        "unknown" /* Unknown */,
        request.seq,
        /*success*/
        false,
        /*performanceData*/
        void 0,
        `Unrecognized JSON command: ${request.command}`
      );
      return { responseRequired: false };
    }
  }
  onMessage(message) {
    var _a, _b, _c, _d, _e, _f, _g;
    this.gcTimer.scheduleCollect();
    let start;
    const currentPerformanceData = this.performanceData;
    if (this.logger.hasLevel(2 /* requestTime */)) {
      start = this.hrtime();
      if (this.logger.hasLevel(3 /* verbose */)) {
        this.logger.info(`request:${indent2(this.toStringMessage(message))}`);
      }
    }
    let request;
    let relevantFile;
    try {
      request = this.parseMessage(message);
      relevantFile = request.arguments && request.arguments.file ? request.arguments : void 0;
      (_a = tracing) == null ? void 0 : _a.instant(tracing.Phase.Session, "request", { seq: request.seq, command: request.command });
      (_b = tracing) == null ? void 0 : _b.push(
        tracing.Phase.Session,
        "executeCommand",
        { seq: request.seq, command: request.command },
        /*separateBeginAndEnd*/
        true
      );
      const { response, responseRequired, performanceData } = this.executeCommand(request);
      (_c = tracing) == null ? void 0 : _c.pop();
      if (this.logger.hasLevel(2 /* requestTime */)) {
        const elapsedTime = hrTimeToMilliseconds(this.hrtime(start)).toFixed(4);
        if (responseRequired) {
          this.logger.perftrc(`${request.seq}::${request.command}: elapsed time (in milliseconds) ${elapsedTime}`);
        } else {
          this.logger.perftrc(`${request.seq}::${request.command}: async elapsed time (in milliseconds) ${elapsedTime}`);
        }
      }
      (_d = tracing) == null ? void 0 : _d.instant(tracing.Phase.Session, "response", { seq: request.seq, command: request.command, success: !!response });
      if (response) {
        this.doOutput(
          response,
          request.command,
          request.seq,
          /*success*/
          true,
          performanceData
        );
      } else if (responseRequired) {
        this.doOutput(
          /*info*/
          void 0,
          request.command,
          request.seq,
          /*success*/
          false,
          performanceData,
          "No content available."
        );
      }
    } catch (err) {
      (_e = tracing) == null ? void 0 : _e.popAll();
      if (err instanceof OperationCanceledException) {
        (_f = tracing) == null ? void 0 : _f.instant(tracing.Phase.Session, "commandCanceled", { seq: request == null ? void 0 : request.seq, command: request == null ? void 0 : request.command });
        this.doOutput(
          { canceled: true },
          request.command,
          request.seq,
          /*success*/
          true,
          this.performanceData
        );
        return;
      }
      this.logErrorWorker(err, this.toStringMessage(message), relevantFile);
      (_g = tracing) == null ? void 0 : _g.instant(tracing.Phase.Session, "commandError", { seq: request == null ? void 0 : request.seq, command: request == null ? void 0 : request.command, message: err.message });
      this.doOutput(
        /*info*/
        void 0,
        request ? request.command : "unknown" /* Unknown */,
        request ? request.seq : 0,
        /*success*/
        false,
        this.performanceData,
        "Error processing request. " + err.message + "\n" + err.stack
      );
    } finally {
      this.performanceData = currentPerformanceData;
    }
  }
  parseMessage(message) {
    return JSON.parse(message);
  }
  toStringMessage(message) {
    return message;
  }
  getFormatOptions(file) {
    return this.projectService.getFormatCodeOptions(file);
  }
  getPreferences(file) {
    return this.projectService.getPreferences(file);
  }
  getHostFormatOptions() {
    return this.projectService.getHostFormatCodeOptions();
  }
  getHostPreferences() {
    return this.projectService.getHostPreferences();
  }
};
function toProtocolPerformanceData(performanceData) {
  const diagnosticsDuration = performanceData.diagnosticsDuration && arrayFrom(performanceData.diagnosticsDuration, ([file, data]) => ({ ...data, file }));
  return { ...performanceData, diagnosticsDuration };
}
function toProtocolTextSpan(textSpan, scriptInfo) {
  return {
    start: scriptInfo.positionToLineOffset(textSpan.start),
    end: scriptInfo.positionToLineOffset(textSpanEnd(textSpan))
  };
}
function toProtocolTextSpanWithContext(span, contextSpan, scriptInfo) {
  const textSpan = toProtocolTextSpan(span, scriptInfo);
  const contextTextSpan = contextSpan && toProtocolTextSpan(contextSpan, scriptInfo);
  return contextTextSpan ? { ...textSpan, contextStart: contextTextSpan.start, contextEnd: contextTextSpan.end } : textSpan;
}
function convertTextChangeToCodeEdit(change, scriptInfo) {
  return { start: positionToLineOffset(scriptInfo, change.span.start), end: positionToLineOffset(scriptInfo, textSpanEnd(change.span)), newText: change.newText };
}
function positionToLineOffset(info, position) {
  return isConfigFile(info) ? locationFromLineAndCharacter(info.getLineAndCharacterOfPosition(position)) : info.positionToLineOffset(position);
}
function convertLinkedEditInfoToRanges(linkedEdit, scriptInfo) {
  const ranges = linkedEdit.ranges.map(
    (r) => {
      return {
        start: scriptInfo.positionToLineOffset(r.start),
        end: scriptInfo.positionToLineOffset(r.start + r.length)
      };
    }
  );
  if (!linkedEdit.wordPattern) return { ranges };
  return { ranges, wordPattern: linkedEdit.wordPattern };
}
function locationFromLineAndCharacter(lc) {
  return { line: lc.line + 1, offset: lc.character + 1 };
}
function convertNewFileTextChangeToCodeEdit(textChanges2) {
  Debug.assert(textChanges2.textChanges.length === 1);
  const change = first(textChanges2.textChanges);
  Debug.assert(change.span.start === 0 && change.span.length === 0);
  return { fileName: textChanges2.fileName, textChanges: [{ start: { line: 0, offset: 0 }, end: { line: 0, offset: 0 }, newText: change.newText }] };
}
function getLocationInNewDocument(oldText, renameFilename, renameLocation, edits) {
  const newText = applyEdits(oldText, renameFilename, edits);
  const { line, character } = computeLineAndCharacterOfPosition(computeLineStarts(newText), renameLocation);
  return { line: line + 1, offset: character + 1 };
}
function applyEdits(text, textFilename, edits) {
  for (const { fileName, textChanges: textChanges2 } of edits) {
    if (fileName !== textFilename) {
      continue;
    }
    for (let i = textChanges2.length - 1; i >= 0; i--) {
      const { newText, span: { start, length: length2 } } = textChanges2[i];
      text = text.slice(0, start) + newText + text.slice(start + length2);
    }
  }
  return text;
}
function referenceEntryToReferencesResponseItem(projectService, { fileName, textSpan, contextSpan, isWriteAccess: isWriteAccess2, isDefinition }, { disableLineTextInReferences }) {
  const scriptInfo = Debug.checkDefined(projectService.getScriptInfo(fileName));
  const span = toProtocolTextSpanWithContext(textSpan, contextSpan, scriptInfo);
  const lineText = disableLineTextInReferences ? void 0 : getLineText(scriptInfo, span);
  return {
    file: fileName,
    ...span,
    lineText,
    isWriteAccess: isWriteAccess2,
    isDefinition
  };
}
function getLineText(scriptInfo, span) {
  const lineSpan = scriptInfo.lineToTextSpan(span.start.line - 1);
  return scriptInfo.getSnapshot().getText(lineSpan.start, textSpanEnd(lineSpan)).replace(/\r|\n/g, "");
}
function isCompletionEntryData(data) {
  return data === void 0 || data && typeof data === "object" && typeof data.exportName === "string" && (data.fileName === void 0 || typeof data.fileName === "string") && (data.ambientModuleName === void 0 || typeof data.ambientModuleName === "string" && (data.isPackageJsonImport === void 0 || typeof data.isPackageJsonImport === "boolean"));
}

// src/server/scriptVersionCache.ts
var lineCollectionCapacity = 4;
var CharRangeSection = /* @__PURE__ */ ((CharRangeSection2) => {
  CharRangeSection2[CharRangeSection2["PreStart"] = 0] = "PreStart";
  CharRangeSection2[CharRangeSection2["Start"] = 1] = "Start";
  CharRangeSection2[CharRangeSection2["Entire"] = 2] = "Entire";
  CharRangeSection2[CharRangeSection2["Mid"] = 3] = "Mid";
  CharRangeSection2[CharRangeSection2["End"] = 4] = "End";
  CharRangeSection2[CharRangeSection2["PostEnd"] = 5] = "PostEnd";
  return CharRangeSection2;
})(CharRangeSection || {});
var EditWalker = class {
  constructor() {
    this.goSubtree = true;
    this.lineIndex = new LineIndex();
    this.endBranch = [];
    this.state = 2 /* Entire */;
    this.initialText = "";
    this.trailingText = "";
    this.lineIndex.root = new LineNode();
    this.startPath = [this.lineIndex.root];
    this.stack = [this.lineIndex.root];
  }
  get done() {
    return false;
  }
  insertLines(insertedText, suppressTrailingText) {
    if (suppressTrailingText) {
      this.trailingText = "";
    }
    if (insertedText) {
      insertedText = this.initialText + insertedText + this.trailingText;
    } else {
      insertedText = this.initialText + this.trailingText;
    }
    const lm = LineIndex.linesFromText(insertedText);
    const lines = lm.lines;
    if (lines.length > 1 && lines[lines.length - 1] === "") {
      lines.pop();
    }
    let branchParent;
    let lastZeroCount;
    for (let k = this.endBranch.length - 1; k >= 0; k--) {
      this.endBranch[k].updateCounts();
      if (this.endBranch[k].charCount() === 0) {
        lastZeroCount = this.endBranch[k];
        if (k > 0) {
          branchParent = this.endBranch[k - 1];
        } else {
          branchParent = this.branchNode;
        }
      }
    }
    if (lastZeroCount) {
      branchParent.remove(lastZeroCount);
    }
    const leafNode = this.startPath[this.startPath.length - 1];
    if (lines.length > 0) {
      leafNode.text = lines[0];
      if (lines.length > 1) {
        let insertedNodes = new Array(lines.length - 1);
        let startNode2 = leafNode;
        for (let i = 1; i < lines.length; i++) {
          insertedNodes[i - 1] = new LineLeaf(lines[i]);
        }
        let pathIndex = this.startPath.length - 2;
        while (pathIndex >= 0) {
          const insertionNode = this.startPath[pathIndex];
          insertedNodes = insertionNode.insertAt(startNode2, insertedNodes);
          pathIndex--;
          startNode2 = insertionNode;
        }
        let insertedNodesLen = insertedNodes.length;
        while (insertedNodesLen > 0) {
          const newRoot = new LineNode();
          newRoot.add(this.lineIndex.root);
          insertedNodes = newRoot.insertAt(this.lineIndex.root, insertedNodes);
          insertedNodesLen = insertedNodes.length;
          this.lineIndex.root = newRoot;
        }
        this.lineIndex.root.updateCounts();
      } else {
        for (let j = this.startPath.length - 2; j >= 0; j--) {
          this.startPath[j].updateCounts();
        }
      }
    } else {
      const insertionNode = this.startPath[this.startPath.length - 2];
      insertionNode.remove(leafNode);
      for (let j = this.startPath.length - 2; j >= 0; j--) {
        this.startPath[j].updateCounts();
      }
    }
    return this.lineIndex;
  }
  post(_relativeStart, _relativeLength, lineCollection) {
    if (lineCollection === this.lineCollectionAtBranch) {
      this.state = 4 /* End */;
    }
    this.stack.pop();
  }
  pre(_relativeStart, _relativeLength, lineCollection, _parent, nodeType) {
    const currentNode = this.stack[this.stack.length - 1];
    if (this.state === 2 /* Entire */ && nodeType === 1 /* Start */) {
      this.state = 1 /* Start */;
      this.branchNode = currentNode;
      this.lineCollectionAtBranch = lineCollection;
    }
    let child;
    function fresh(node) {
      if (node.isLeaf()) {
        return new LineLeaf("");
      } else return new LineNode();
    }
    switch (nodeType) {
      case 0 /* PreStart */:
        this.goSubtree = false;
        if (this.state !== 4 /* End */) {
          currentNode.add(lineCollection);
        }
        break;
      case 1 /* Start */:
        if (this.state === 4 /* End */) {
          this.goSubtree = false;
        } else {
          child = fresh(lineCollection);
          currentNode.add(child);
          this.startPath.push(child);
        }
        break;
      case 2 /* Entire */:
        if (this.state !== 4 /* End */) {
          child = fresh(lineCollection);
          currentNode.add(child);
          this.startPath.push(child);
        } else {
          if (!lineCollection.isLeaf()) {
            child = fresh(lineCollection);
            currentNode.add(child);
            this.endBranch.push(child);
          }
        }
        break;
      case 3 /* Mid */:
        this.goSubtree = false;
        break;
      case 4 /* End */:
        if (this.state !== 4 /* End */) {
          this.goSubtree = false;
        } else {
          if (!lineCollection.isLeaf()) {
            child = fresh(lineCollection);
            currentNode.add(child);
            this.endBranch.push(child);
          }
        }
        break;
      case 5 /* PostEnd */:
        this.goSubtree = false;
        if (this.state !== 1 /* Start */) {
          currentNode.add(lineCollection);
        }
        break;
    }
    if (this.goSubtree) {
      this.stack.push(child);
    }
  }
  // just gather text from the leaves
  leaf(relativeStart, relativeLength, ll) {
    if (this.state === 1 /* Start */) {
      this.initialText = ll.text.substring(0, relativeStart);
    } else if (this.state === 2 /* Entire */) {
      this.initialText = ll.text.substring(0, relativeStart);
      this.trailingText = ll.text.substring(relativeStart + relativeLength);
    } else {
      this.trailingText = ll.text.substring(relativeStart + relativeLength);
    }
  }
};
var TextChange9 = class {
  constructor(pos, deleteLen, insertedText) {
    this.pos = pos;
    this.deleteLen = deleteLen;
    this.insertedText = insertedText;
  }
  getTextChangeRange() {
    return createTextChangeRange(createTextSpan(this.pos, this.deleteLen), this.insertedText ? this.insertedText.length : 0);
  }
};
var _ScriptVersionCache = class _ScriptVersionCache {
  constructor() {
    this.changes = [];
    this.versions = new Array(_ScriptVersionCache.maxVersions);
    this.minVersion = 0;
    // no versions earlier than min version will maintain change history
    this.currentVersion = 0;
  }
  versionToIndex(version2) {
    if (version2 < this.minVersion || version2 > this.currentVersion) {
      return void 0;
    }
    return version2 % _ScriptVersionCache.maxVersions;
  }
  currentVersionToIndex() {
    return this.currentVersion % _ScriptVersionCache.maxVersions;
  }
  // REVIEW: can optimize by coalescing simple edits
  edit(pos, deleteLen, insertedText) {
    this.changes.push(new TextChange9(pos, deleteLen, insertedText));
    if (this.changes.length > _ScriptVersionCache.changeNumberThreshold || deleteLen > _ScriptVersionCache.changeLengthThreshold || insertedText && insertedText.length > _ScriptVersionCache.changeLengthThreshold) {
      this.getSnapshot();
    }
  }
  getSnapshot() {
    return this._getSnapshot();
  }
  _getSnapshot() {
    let snap = this.versions[this.currentVersionToIndex()];
    if (this.changes.length > 0) {
      let snapIndex = snap.index;
      for (const change of this.changes) {
        snapIndex = snapIndex.edit(change.pos, change.deleteLen, change.insertedText);
      }
      snap = new LineIndexSnapshot(this.currentVersion + 1, this, snapIndex, this.changes);
      this.currentVersion = snap.version;
      this.versions[this.currentVersionToIndex()] = snap;
      this.changes = [];
      if (this.currentVersion - this.minVersion >= _ScriptVersionCache.maxVersions) {
        this.minVersion = this.currentVersion - _ScriptVersionCache.maxVersions + 1;
      }
    }
    return snap;
  }
  getSnapshotVersion() {
    return this._getSnapshot().version;
  }
  getAbsolutePositionAndLineText(oneBasedLine) {
    return this._getSnapshot().index.lineNumberToInfo(oneBasedLine);
  }
  lineOffsetToPosition(line, column) {
    return this._getSnapshot().index.absolutePositionOfStartOfLine(line) + (column - 1);
  }
  positionToLineOffset(position) {
    return this._getSnapshot().index.positionToLineOffset(position);
  }
  lineToTextSpan(line) {
    const index = this._getSnapshot().index;
    const { lineText, absolutePosition } = index.lineNumberToInfo(line + 1);
    const len = lineText !== void 0 ? lineText.length : index.absolutePositionOfStartOfLine(line + 2) - absolutePosition;
    return createTextSpan(absolutePosition, len);
  }
  getTextChangesBetweenVersions(oldVersion, newVersion) {
    if (oldVersion < newVersion) {
      if (oldVersion >= this.minVersion) {
        const textChangeRanges = [];
        for (let i = oldVersion + 1; i <= newVersion; i++) {
          const snap = this.versions[this.versionToIndex(i)];
          for (const textChange of snap.changesSincePreviousVersion) {
            textChangeRanges.push(textChange.getTextChangeRange());
          }
        }
        return collapseTextChangeRangesAcrossMultipleVersions(textChangeRanges);
      } else {
        return void 0;
      }
    } else {
      return unchangedTextChangeRange;
    }
  }
  getLineCount() {
    return this._getSnapshot().index.getLineCount();
  }
  static fromString(script) {
    const svc = new _ScriptVersionCache();
    const snap = new LineIndexSnapshot(0, svc, new LineIndex());
    svc.versions[svc.currentVersion] = snap;
    const lm = LineIndex.linesFromText(script);
    snap.index.load(lm.lines);
    return svc;
  }
};
_ScriptVersionCache.changeNumberThreshold = 8;
_ScriptVersionCache.changeLengthThreshold = 256;
_ScriptVersionCache.maxVersions = 8;
var ScriptVersionCache = _ScriptVersionCache;
var LineIndexSnapshot = class _LineIndexSnapshot {
  constructor(version2, cache, index, changesSincePreviousVersion = emptyArray2) {
    this.version = version2;
    this.cache = cache;
    this.index = index;
    this.changesSincePreviousVersion = changesSincePreviousVersion;
  }
  getText(rangeStart, rangeEnd) {
    return this.index.getText(rangeStart, rangeEnd - rangeStart);
  }
  getLength() {
    return this.index.getLength();
  }
  getChangeRange(oldSnapshot) {
    if (oldSnapshot instanceof _LineIndexSnapshot && this.cache === oldSnapshot.cache) {
      if (this.version <= oldSnapshot.version) {
        return unchangedTextChangeRange;
      } else {
        return this.cache.getTextChangesBetweenVersions(oldSnapshot.version, this.version);
      }
    }
  }
};
var LineIndex = class _LineIndex {
  constructor() {
    // set this to true to check each edit for accuracy
    this.checkEdits = false;
  }
  absolutePositionOfStartOfLine(oneBasedLine) {
    return this.lineNumberToInfo(oneBasedLine).absolutePosition;
  }
  positionToLineOffset(position) {
    const { oneBasedLine, zeroBasedColumn } = this.root.charOffsetToLineInfo(1, position);
    return { line: oneBasedLine, offset: zeroBasedColumn + 1 };
  }
  positionToColumnAndLineText(position) {
    return this.root.charOffsetToLineInfo(1, position);
  }
  getLineCount() {
    return this.root.lineCount();
  }
  lineNumberToInfo(oneBasedLine) {
    const lineCount = this.getLineCount();
    if (oneBasedLine <= lineCount) {
      const { position, leaf } = this.root.lineNumberToInfo(oneBasedLine, 0);
      return { absolutePosition: position, lineText: leaf && leaf.text };
    } else {
      return { absolutePosition: this.root.charCount(), lineText: void 0 };
    }
  }
  load(lines) {
    if (lines.length > 0) {
      const leaves = [];
      for (let i = 0; i < lines.length; i++) {
        leaves[i] = new LineLeaf(lines[i]);
      }
      this.root = _LineIndex.buildTreeFromBottom(leaves);
    } else {
      this.root = new LineNode();
    }
  }
  walk(rangeStart, rangeLength, walkFns) {
    this.root.walk(rangeStart, rangeLength, walkFns);
  }
  getText(rangeStart, rangeLength) {
    let accum = "";
    if (rangeLength > 0 && rangeStart < this.root.charCount()) {
      this.walk(rangeStart, rangeLength, {
        goSubtree: true,
        done: false,
        leaf: (relativeStart, relativeLength, ll) => {
          accum = accum.concat(ll.text.substring(relativeStart, relativeStart + relativeLength));
        }
      });
    }
    return accum;
  }
  getLength() {
    return this.root.charCount();
  }
  every(f, rangeStart, rangeEnd) {
    if (!rangeEnd) {
      rangeEnd = this.root.charCount();
    }
    const walkFns = {
      goSubtree: true,
      done: false,
      leaf(relativeStart, relativeLength, ll) {
        if (!f(ll, relativeStart, relativeLength)) {
          this.done = true;
        }
      }
    };
    this.walk(rangeStart, rangeEnd - rangeStart, walkFns);
    return !walkFns.done;
  }
  edit(pos, deleteLength, newText) {
    if (this.root.charCount() === 0) {
      Debug.assert(deleteLength === 0);
      if (newText !== void 0) {
        this.load(_LineIndex.linesFromText(newText).lines);
        return this;
      }
      return void 0;
    } else {
      let checkText;
      if (this.checkEdits) {
        const source = this.getText(0, this.root.charCount());
        checkText = source.slice(0, pos) + newText + source.slice(pos + deleteLength);
      }
      const walker = new EditWalker();
      let suppressTrailingText = false;
      if (pos >= this.root.charCount()) {
        pos = this.root.charCount() - 1;
        const endString = this.getText(pos, 1);
        if (newText) {
          newText = endString + newText;
        } else {
          newText = endString;
        }
        deleteLength = 0;
        suppressTrailingText = true;
      } else if (deleteLength > 0) {
        const e = pos + deleteLength;
        const { zeroBasedColumn, lineText } = this.positionToColumnAndLineText(e);
        if (zeroBasedColumn === 0) {
          deleteLength += lineText.length;
          newText = newText ? newText + lineText : lineText;
        }
      }
      this.root.walk(pos, deleteLength, walker);
      walker.insertLines(newText, suppressTrailingText);
      if (this.checkEdits) {
        const updatedText = walker.lineIndex.getText(0, walker.lineIndex.getLength());
        Debug.assert(checkText === updatedText, "buffer edit mismatch");
      }
      return walker.lineIndex;
    }
  }
  static buildTreeFromBottom(nodes) {
    if (nodes.length < lineCollectionCapacity) {
      return new LineNode(nodes);
    }
    const interiorNodes = new Array(Math.ceil(nodes.length / lineCollectionCapacity));
    let nodeIndex = 0;
    for (let i = 0; i < interiorNodes.length; i++) {
      const end = Math.min(nodeIndex + lineCollectionCapacity, nodes.length);
      interiorNodes[i] = new LineNode(nodes.slice(nodeIndex, end));
      nodeIndex = end;
    }
    return this.buildTreeFromBottom(interiorNodes);
  }
  static linesFromText(text) {
    const lineMap = computeLineStarts(text);
    if (lineMap.length === 0) {
      return { lines: [], lineMap };
    }
    const lines = new Array(lineMap.length);
    const lc = lineMap.length - 1;
    for (let lmi = 0; lmi < lc; lmi++) {
      lines[lmi] = text.substring(lineMap[lmi], lineMap[lmi + 1]);
    }
    const endText = text.substring(lineMap[lc]);
    if (endText.length > 0) {
      lines[lc] = endText;
    } else {
      lines.pop();
    }
    return { lines, lineMap };
  }
};
var LineNode = class _LineNode {
  constructor(children = []) {
    this.children = children;
    this.totalChars = 0;
    this.totalLines = 0;
    if (children.length) this.updateCounts();
  }
  isLeaf() {
    return false;
  }
  updateCounts() {
    this.totalChars = 0;
    this.totalLines = 0;
    for (const child of this.children) {
      this.totalChars += child.charCount();
      this.totalLines += child.lineCount();
    }
  }
  execWalk(rangeStart, rangeLength, walkFns, childIndex, nodeType) {
    if (walkFns.pre) {
      walkFns.pre(rangeStart, rangeLength, this.children[childIndex], this, nodeType);
    }
    if (walkFns.goSubtree) {
      this.children[childIndex].walk(rangeStart, rangeLength, walkFns);
      if (walkFns.post) {
        walkFns.post(rangeStart, rangeLength, this.children[childIndex], this, nodeType);
      }
    } else {
      walkFns.goSubtree = true;
    }
    return walkFns.done;
  }
  skipChild(relativeStart, relativeLength, childIndex, walkFns, nodeType) {
    if (walkFns.pre && !walkFns.done) {
      walkFns.pre(relativeStart, relativeLength, this.children[childIndex], this, nodeType);
      walkFns.goSubtree = true;
    }
  }
  walk(rangeStart, rangeLength, walkFns) {
    let childIndex = 0;
    let childCharCount = this.children[childIndex].charCount();
    let adjustedStart = rangeStart;
    while (adjustedStart >= childCharCount) {
      this.skipChild(adjustedStart, rangeLength, childIndex, walkFns, 0 /* PreStart */);
      adjustedStart -= childCharCount;
      childIndex++;
      childCharCount = this.children[childIndex].charCount();
    }
    if (adjustedStart + rangeLength <= childCharCount) {
      if (this.execWalk(adjustedStart, rangeLength, walkFns, childIndex, 2 /* Entire */)) {
        return;
      }
    } else {
      if (this.execWalk(adjustedStart, childCharCount - adjustedStart, walkFns, childIndex, 1 /* Start */)) {
        return;
      }
      let adjustedLength = rangeLength - (childCharCount - adjustedStart);
      childIndex++;
      const child = this.children[childIndex];
      childCharCount = child.charCount();
      while (adjustedLength > childCharCount) {
        if (this.execWalk(0, childCharCount, walkFns, childIndex, 3 /* Mid */)) {
          return;
        }
        adjustedLength -= childCharCount;
        childIndex++;
        childCharCount = this.children[childIndex].charCount();
      }
      if (adjustedLength > 0) {
        if (this.execWalk(0, adjustedLength, walkFns, childIndex, 4 /* End */)) {
          return;
        }
      }
    }
    if (walkFns.pre) {
      const clen = this.children.length;
      if (childIndex < clen - 1) {
        for (let ej = childIndex + 1; ej < clen; ej++) {
          this.skipChild(0, 0, ej, walkFns, 5 /* PostEnd */);
        }
      }
    }
  }
  // Input position is relative to the start of this node.
  // Output line number is absolute.
  charOffsetToLineInfo(lineNumberAccumulator, relativePosition) {
    if (this.children.length === 0) {
      return { oneBasedLine: lineNumberAccumulator, zeroBasedColumn: relativePosition, lineText: void 0 };
    }
    for (const child of this.children) {
      if (child.charCount() > relativePosition) {
        if (child.isLeaf()) {
          return { oneBasedLine: lineNumberAccumulator, zeroBasedColumn: relativePosition, lineText: child.text };
        } else {
          return child.charOffsetToLineInfo(lineNumberAccumulator, relativePosition);
        }
      } else {
        relativePosition -= child.charCount();
        lineNumberAccumulator += child.lineCount();
      }
    }
    const lineCount = this.lineCount();
    if (lineCount === 0) {
      return { oneBasedLine: 1, zeroBasedColumn: 0, lineText: void 0 };
    }
    const leaf = Debug.checkDefined(this.lineNumberToInfo(lineCount, 0).leaf);
    return { oneBasedLine: lineCount, zeroBasedColumn: leaf.charCount(), lineText: void 0 };
  }
  /**
   * Input line number is relative to the start of this node.
   * Output line number is relative to the child.
   * positionAccumulator will be an absolute position once relativeLineNumber reaches 0.
   */
  lineNumberToInfo(relativeOneBasedLine, positionAccumulator) {
    for (const child of this.children) {
      const childLineCount = child.lineCount();
      if (childLineCount >= relativeOneBasedLine) {
        return child.isLeaf() ? { position: positionAccumulator, leaf: child } : child.lineNumberToInfo(relativeOneBasedLine, positionAccumulator);
      } else {
        relativeOneBasedLine -= childLineCount;
        positionAccumulator += child.charCount();
      }
    }
    return { position: positionAccumulator, leaf: void 0 };
  }
  splitAfter(childIndex) {
    let splitNode;
    const clen = this.children.length;
    childIndex++;
    const endLength = childIndex;
    if (childIndex < clen) {
      splitNode = new _LineNode();
      while (childIndex < clen) {
        splitNode.add(this.children[childIndex]);
        childIndex++;
      }
      splitNode.updateCounts();
    }
    this.children.length = endLength;
    return splitNode;
  }
  remove(child) {
    const childIndex = this.findChildIndex(child);
    const clen = this.children.length;
    if (childIndex < clen - 1) {
      for (let i = childIndex; i < clen - 1; i++) {
        this.children[i] = this.children[i + 1];
      }
    }
    this.children.pop();
  }
  findChildIndex(child) {
    const childIndex = this.children.indexOf(child);
    Debug.assert(childIndex !== -1);
    return childIndex;
  }
  insertAt(child, nodes) {
    let childIndex = this.findChildIndex(child);
    const clen = this.children.length;
    const nodeCount = nodes.length;
    if (clen < lineCollectionCapacity && childIndex === clen - 1 && nodeCount === 1) {
      this.add(nodes[0]);
      this.updateCounts();
      return [];
    } else {
      const shiftNode = this.splitAfter(childIndex);
      let nodeIndex = 0;
      childIndex++;
      while (childIndex < lineCollectionCapacity && nodeIndex < nodeCount) {
        this.children[childIndex] = nodes[nodeIndex];
        childIndex++;
        nodeIndex++;
      }
      let splitNodes = [];
      let splitNodeCount = 0;
      if (nodeIndex < nodeCount) {
        splitNodeCount = Math.ceil((nodeCount - nodeIndex) / lineCollectionCapacity);
        splitNodes = new Array(splitNodeCount);
        let splitNodeIndex = 0;
        for (let i = 0; i < splitNodeCount; i++) {
          splitNodes[i] = new _LineNode();
        }
        let splitNode = splitNodes[0];
        while (nodeIndex < nodeCount) {
          splitNode.add(nodes[nodeIndex]);
          nodeIndex++;
          if (splitNode.children.length === lineCollectionCapacity) {
            splitNodeIndex++;
            splitNode = splitNodes[splitNodeIndex];
          }
        }
        for (let i = splitNodes.length - 1; i >= 0; i--) {
          if (splitNodes[i].children.length === 0) {
            splitNodes.pop();
          }
        }
      }
      if (shiftNode) {
        splitNodes.push(shiftNode);
      }
      this.updateCounts();
      for (let i = 0; i < splitNodeCount; i++) {
        splitNodes[i].updateCounts();
      }
      return splitNodes;
    }
  }
  // assume there is room for the item; return true if more room
  add(collection) {
    this.children.push(collection);
    Debug.assert(this.children.length <= lineCollectionCapacity);
  }
  charCount() {
    return this.totalChars;
  }
  lineCount() {
    return this.totalLines;
  }
};
var LineLeaf = class {
  constructor(text) {
    this.text = text;
  }
  isLeaf() {
    return true;
  }
  walk(rangeStart, rangeLength, walkFns) {
    walkFns.leaf(rangeStart, rangeLength, this);
  }
  charCount() {
    return this.text.length;
  }
  lineCount() {
    return 1;
  }
};

// src/server/typingInstallerAdapter.ts
var _TypingsInstallerAdapter = class _TypingsInstallerAdapter {
  constructor(telemetryEnabled, logger, host, globalTypingsCacheLocation, event, maxActiveRequestCount) {
    this.telemetryEnabled = telemetryEnabled;
    this.logger = logger;
    this.host = host;
    this.globalTypingsCacheLocation = globalTypingsCacheLocation;
    this.event = event;
    this.maxActiveRequestCount = maxActiveRequestCount;
    this.activeRequestCount = 0;
    this.requestQueue = createQueue();
    this.requestMap = /* @__PURE__ */ new Map();
    // Maps project name to newest requestQueue entry for that project
    /** We will lazily request the types registry on the first call to `isKnownTypesPackageName` and store it in `typesRegistryCache`. */
    this.requestedRegistry = false;
    this.packageInstallId = 0;
  }
  isKnownTypesPackageName(name) {
    var _a;
    const validationResult = ts_JsTyping_exports.validatePackageName(name);
    if (validationResult !== ts_JsTyping_exports.NameValidationResult.Ok) {
      return false;
    }
    if (!this.requestedRegistry) {
      this.requestedRegistry = true;
      this.installer.send({ kind: "typesRegistry" });
    }
    return !!((_a = this.typesRegistryCache) == null ? void 0 : _a.has(name));
  }
  installPackage(options) {
    this.packageInstallId++;
    const request = { kind: "installPackage", ...options, id: this.packageInstallId };
    const promise = new Promise((resolve, reject) => {
      (this.packageInstalledPromise ?? (this.packageInstalledPromise = /* @__PURE__ */ new Map())).set(this.packageInstallId, { resolve, reject });
    });
    this.installer.send(request);
    return promise;
  }
  attach(projectService) {
    this.projectService = projectService;
    this.installer = this.createInstallerProcess();
  }
  onProjectClosed(p) {
    this.installer.send({ projectName: p.getProjectName(), kind: "closeProject" });
  }
  enqueueInstallTypingsRequest(project, typeAcquisition, unresolvedImports) {
    const request = createInstallTypingsRequest(project, typeAcquisition, unresolvedImports);
    if (this.logger.hasLevel(3 /* verbose */)) {
      this.logger.info(`TIAdapter:: Scheduling throttled operation:${stringifyIndented(request)}`);
    }
    if (this.activeRequestCount < this.maxActiveRequestCount) {
      this.scheduleRequest(request);
    } else {
      if (this.logger.hasLevel(3 /* verbose */)) {
        this.logger.info(`TIAdapter:: Deferring request for: ${request.projectName}`);
      }
      this.requestQueue.enqueue(request);
      this.requestMap.set(request.projectName, request);
    }
  }
  handleMessage(response) {
    var _a, _b;
    if (this.logger.hasLevel(3 /* verbose */)) {
      this.logger.info(`TIAdapter:: Received response:${stringifyIndented(response)}`);
    }
    switch (response.kind) {
      case EventTypesRegistry:
        this.typesRegistryCache = new Map(Object.entries(response.typesRegistry));
        break;
      case ActionPackageInstalled: {
        const promise = (_a = this.packageInstalledPromise) == null ? void 0 : _a.get(response.id);
        Debug.assertIsDefined(promise, "Should find the promise for package install");
        (_b = this.packageInstalledPromise) == null ? void 0 : _b.delete(response.id);
        if (response.success) {
          promise.resolve({ successMessage: response.message });
        } else {
          promise.reject(response.message);
        }
        this.projectService.updateTypingsForProject(response);
        this.event(response, "setTypings");
        break;
      }
      case EventInitializationFailed: {
        const body = {
          message: response.message
        };
        const eventName = "typesInstallerInitializationFailed";
        this.event(body, eventName);
        break;
      }
      case EventBeginInstallTypes: {
        const body = {
          eventId: response.eventId,
          packages: response.packagesToInstall
        };
        const eventName = "beginInstallTypes";
        this.event(body, eventName);
        break;
      }
      case EventEndInstallTypes: {
        if (this.telemetryEnabled) {
          const body2 = {
            telemetryEventName: "typingsInstalled",
            payload: {
              installedPackages: response.packagesToInstall.join(","),
              installSuccess: response.installSuccess,
              typingsInstallerVersion: response.typingsInstallerVersion
            }
          };
          const eventName2 = "telemetry";
          this.event(body2, eventName2);
        }
        const body = {
          eventId: response.eventId,
          packages: response.packagesToInstall,
          success: response.installSuccess
        };
        const eventName = "endInstallTypes";
        this.event(body, eventName);
        break;
      }
      case ActionInvalidate: {
        this.projectService.updateTypingsForProject(response);
        break;
      }
      case ActionSet: {
        if (this.activeRequestCount > 0) {
          this.activeRequestCount--;
        } else {
          Debug.fail("TIAdapter:: Received too many responses");
        }
        while (!this.requestQueue.isEmpty()) {
          const queuedRequest = this.requestQueue.dequeue();
          if (this.requestMap.get(queuedRequest.projectName) === queuedRequest) {
            this.requestMap.delete(queuedRequest.projectName);
            this.scheduleRequest(queuedRequest);
            break;
          }
          if (this.logger.hasLevel(3 /* verbose */)) {
            this.logger.info(`TIAdapter:: Skipping defunct request for: ${queuedRequest.projectName}`);
          }
        }
        this.projectService.updateTypingsForProject(response);
        this.event(response, "setTypings");
        break;
      }
      case ActionWatchTypingLocations:
        this.projectService.watchTypingLocations(response);
        break;
      default:
        assertType(response);
    }
  }
  scheduleRequest(request) {
    if (this.logger.hasLevel(3 /* verbose */)) {
      this.logger.info(`TIAdapter:: Scheduling request for: ${request.projectName}`);
    }
    this.activeRequestCount++;
    this.host.setTimeout(
      () => {
        if (this.logger.hasLevel(3 /* verbose */)) {
          this.logger.info(`TIAdapter:: Sending request:${stringifyIndented(request)}`);
        }
        this.installer.send(request);
      },
      _TypingsInstallerAdapter.requestDelayMillis,
      `${request.projectName}::${request.kind}`
    );
  }
};
// This number is essentially arbitrary.  Processing more than one typings request
// at a time makes sense, but having too many in the pipe results in a hang
// (see https://github.com/nodejs/node/issues/7657).
// It would be preferable to base our limit on the amount of space left in the
// buffer, but we have yet to find a way to retrieve that value.
_TypingsInstallerAdapter.requestDelayMillis = 100;
var TypingsInstallerAdapter = _TypingsInstallerAdapter;

// src/typescript/_namespaces/ts.server.ts
var ts_server_exports4 = {};
__export(ts_server_exports4, {
  ActionInvalidate: () => ActionInvalidate,
  ActionPackageInstalled: () => ActionPackageInstalled,
  ActionSet: () => ActionSet,
  ActionWatchTypingLocations: () => ActionWatchTypingLocations,
  Arguments: () => Arguments,
  AutoImportProviderProject: () => AutoImportProviderProject,
  AuxiliaryProject: () => AuxiliaryProject,
  CharRangeSection: () => CharRangeSection,
  CloseFileWatcherEvent: () => CloseFileWatcherEvent,
  CommandNames: () => CommandNames,
  ConfigFileDiagEvent: () => ConfigFileDiagEvent,
  ConfiguredProject: () => ConfiguredProject2,
  ConfiguredProjectLoadKind: () => ConfiguredProjectLoadKind,
  CreateDirectoryWatcherEvent: () => CreateDirectoryWatcherEvent,
  CreateFileWatcherEvent: () => CreateFileWatcherEvent,
  Errors: () => Errors,
  EventBeginInstallTypes: () => EventBeginInstallTypes,
  EventEndInstallTypes: () => EventEndInstallTypes,
  EventInitializationFailed: () => EventInitializationFailed,
  EventTypesRegistry: () => EventTypesRegistry,
  ExternalProject: () => ExternalProject,
  GcTimer: () => GcTimer,
  InferredProject: () => InferredProject2,
  LargeFileReferencedEvent: () => LargeFileReferencedEvent,
  LineIndex: () => LineIndex,
  LineLeaf: () => LineLeaf,
  LineNode: () => LineNode,
  LogLevel: () => LogLevel2,
  Msg: () => Msg,
  OpenFileInfoTelemetryEvent: () => OpenFileInfoTelemetryEvent,
  Project: () => Project2,
  ProjectInfoTelemetryEvent: () => ProjectInfoTelemetryEvent,
  ProjectKind: () => ProjectKind,
  ProjectLanguageServiceStateEvent: () => ProjectLanguageServiceStateEvent,
  ProjectLoadingFinishEvent: () => ProjectLoadingFinishEvent,
  ProjectLoadingStartEvent: () => ProjectLoadingStartEvent,
  ProjectService: () => ProjectService2,
  ProjectsUpdatedInBackgroundEvent: () => ProjectsUpdatedInBackgroundEvent,
  ScriptInfo: () => ScriptInfo,
  ScriptVersionCache: () => ScriptVersionCache,
  Session: () => Session3,
  TextStorage: () => TextStorage,
  ThrottledOperations: () => ThrottledOperations,
  TypingsInstallerAdapter: () => TypingsInstallerAdapter,
  allFilesAreJsOrDts: () => allFilesAreJsOrDts,
  allRootFilesAreJsOrDts: () => allRootFilesAreJsOrDts,
  asNormalizedPath: () => asNormalizedPath,
  convertCompilerOptions: () => convertCompilerOptions,
  convertFormatOptions: () => convertFormatOptions,
  convertScriptKindName: () => convertScriptKindName,
  convertTypeAcquisition: () => convertTypeAcquisition,
  convertUserPreferences: () => convertUserPreferences,
  convertWatchOptions: () => convertWatchOptions,
  countEachFileTypes: () => countEachFileTypes,
  createInstallTypingsRequest: () => createInstallTypingsRequest,
  createModuleSpecifierCache: () => createModuleSpecifierCache,
  createNormalizedPathMap: () => createNormalizedPathMap,
  createPackageJsonCache: () => createPackageJsonCache,
  createSortedArray: () => createSortedArray2,
  emptyArray: () => emptyArray2,
  findArgument: () => findArgument,
  formatDiagnosticToProtocol: () => formatDiagnosticToProtocol,
  formatMessage: () => formatMessage2,
  getBaseConfigFileName: () => getBaseConfigFileName,
  getLocationInNewDocument: () => getLocationInNewDocument,
  hasArgument: () => hasArgument,
  hasNoTypeScriptSource: () => hasNoTypeScriptSource,
  indent: () => indent2,
  isBackgroundProject: () => isBackgroundProject,
  isConfigFile: () => isConfigFile,
  isConfiguredProject: () => isConfiguredProject,
  isDynamicFileName: () => isDynamicFileName,
  isExternalProject: () => isExternalProject,
  isInferredProject: () => isInferredProject,
  isInferredProjectName: () => isInferredProjectName,
  isProjectDeferredClose: () => isProjectDeferredClose,
  makeAutoImportProviderProjectName: () => makeAutoImportProviderProjectName,
  makeAuxiliaryProjectName: () => makeAuxiliaryProjectName,
  makeInferredProjectName: () => makeInferredProjectName,
  maxFileSize: () => maxFileSize,
  maxProgramSizeForNonTsFiles: () => maxProgramSizeForNonTsFiles,
  normalizedPathToPath: () => normalizedPathToPath,
  nowString: () => nowString,
  nullCancellationToken: () => nullCancellationToken,
  nullTypingsInstaller: () => nullTypingsInstaller,
  protocol: () => ts_server_protocol_exports,
  stringifyIndented: () => stringifyIndented,
  toEvent: () => toEvent,
  toNormalizedPath: () => toNormalizedPath,
  tryConvertScriptKindName: () => tryConvertScriptKindName,
  typingsInstaller: () => ts_server_typingsInstaller_exports,
  updateProjectIfDirty: () => updateProjectIfDirty
});

// src/typescript/typescript.ts
if (typeof console !== "undefined") {
  Debug.loggingHost = {
    log(level, s) {
      switch (level) {
        case 1 /* Error */:
          return console.error(s);
        case 2 /* Warning */:
          return console.warn(s);
        case 3 /* Info */:
          return console.log(s);
        case 4 /* Verbose */:
          return console.log(s);
      }
    }
  };
}
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
  ANONYMOUS,
  AccessFlags,
  AssertionLevel,
  AssignmentDeclarationKind,
  AssignmentKind,
  Associativity,
  BreakpointResolver,
  BuilderFileEmit,
  BuilderProgramKind,
  BuilderState,
  CallHierarchy,
  CharacterCodes,
  CheckFlags,
  CheckMode,
  ClassificationType,
  ClassificationTypeNames,
  CommentDirectiveType,
  Comparison,
  CompletionInfoFlags,
  CompletionTriggerKind,
  Completions,
  ContainerFlags,
  ContextFlags,
  Debug,
  DiagnosticCategory,
  Diagnostics,
  DocumentHighlights,
  ElementFlags,
  EmitFlags,
  EmitHint,
  EmitOnly,
  EndOfLineState,
  ExitStatus,
  ExportKind,
  Extension,
  ExternalEmitHelpers,
  FileIncludeKind,
  FilePreprocessingDiagnosticsKind,
  FileSystemEntryKind,
  FileWatcherEventKind,
  FindAllReferences,
  FlattenLevel,
  FlowFlags,
  ForegroundColorEscapeSequences,
  FunctionFlags,
  GeneratedIdentifierFlags,
  GetLiteralTextFlags,
  GoToDefinition,
  HighlightSpanKind,
  IdentifierNameMap,
  ImportKind,
  ImportsNotUsedAsValues,
  IndentStyle,
  IndexFlags,
  IndexKind,
  InferenceFlags,
  InferencePriority,
  InlayHintKind,
  InlayHints,
  InternalEmitFlags,
  InternalNodeBuilderFlags,
  InternalSymbolName,
  IntersectionFlags,
  InvalidatedProjectKind,
  JSDocParsingMode,
  JsDoc,
  JsTyping,
  JsxEmit,
  JsxFlags,
  JsxReferenceKind,
  LanguageFeatureMinimumTarget,
  LanguageServiceMode,
  LanguageVariant,
  LexicalEnvironmentFlags,
  ListFormat,
  LogLevel,
  MapCode,
  MemberOverrideStatus,
  ModifierFlags,
  ModuleDetectionKind,
  ModuleInstanceState,
  ModuleKind,
  ModuleResolutionKind,
  ModuleSpecifierEnding,
  NavigateTo,
  NavigationBar,
  NewLineKind,
  NodeBuilderFlags,
  NodeCheckFlags,
  NodeFactoryFlags,
  NodeFlags,
  NodeResolutionFeatures,
  ObjectFlags,
  OperationCanceledException,
  OperatorPrecedence,
  OrganizeImports,
  OrganizeImportsMode,
  OuterExpressionKinds,
  OutliningElementsCollector,
  OutliningSpanKind,
  OutputFileType,
  PackageJsonAutoImportPreference,
  PackageJsonDependencyGroup,
  PatternMatchKind,
  PollingInterval,
  PollingWatchKind,
  PragmaKindFlags,
  PredicateSemantics,
  PrivateIdentifierKind,
  ProcessLevel,
  ProgramUpdateLevel,
  QuotePreference,
  RegularExpressionFlags,
  RelationComparisonResult,
  Rename,
  ScriptElementKind,
  ScriptElementKindModifier,
  ScriptKind,
  ScriptSnapshot,
  ScriptTarget,
  SemanticClassificationFormat,
  SemanticMeaning,
  SemicolonPreference,
  SignatureCheckMode,
  SignatureFlags,
  SignatureHelp,
  SignatureInfo,
  SignatureKind,
  SmartSelectionRange,
  SnippetKind,
  StatisticType,
  StructureIsReused,
  SymbolAccessibility,
  SymbolDisplay,
  SymbolDisplayPartKind,
  SymbolFlags,
  SymbolFormatFlags,
  SyntaxKind,
  Ternary,
  ThrottledCancellationToken,
  TokenClass,
  TokenFlags,
  TransformFlags,
  TypeFacts,
  TypeFlags,
  TypeFormatFlags,
  TypeMapKind,
  TypePredicateKind,
  TypeReferenceSerializationKind,
  UnionReduction,
  UpToDateStatusType,
  VarianceFlags,
  Version,
  VersionRange,
  WatchDirectoryFlags,
  WatchDirectoryKind,
  WatchFileKind,
  WatchLogLevel,
  WatchType,
  accessPrivateIdentifier,
  addEmitFlags,
  addEmitHelper,
  addEmitHelpers,
  addInternalEmitFlags,
  addNodeFactoryPatcher,
  addObjectAllocatorPatcher,
  addRange,
  addRelatedInfo,
  addSyntheticLeadingComment,
  addSyntheticTrailingComment,
  addToSeen,
  advancedAsyncSuperHelper,
  affectsDeclarationPathOptionDeclarations,
  affectsEmitOptionDeclarations,
  allKeysStartWithDot,
  altDirectorySeparator,
  and,
  append,
  appendIfUnique,
  arrayFrom,
  arrayIsEqualTo,
  arrayIsHomogeneous,
  arrayOf,
  arrayReverseIterator,
  arrayToMap,
  arrayToMultiMap,
  arrayToNumericMap,
  assertType,
  assign,
  asyncSuperHelper,
  attachFileToDiagnostics,
  base64decode,
  base64encode,
  binarySearch,
  binarySearchKey,
  bindSourceFile,
  breakIntoCharacterSpans,
  breakIntoWordSpans,
  buildLinkParts,
  buildOpts,
  buildOverload,
  bundlerModuleNameResolver,
  canBeConvertedToAsync,
  canHaveDecorators,
  canHaveExportModifier,
  canHaveFlowNode,
  canHaveIllegalDecorators,
  canHaveIllegalModifiers,
  canHaveIllegalType,
  canHaveIllegalTypeParameters,
  canHaveJSDoc,
  canHaveLocals,
  canHaveModifiers,
  canHaveModuleSpecifier,
  canHaveSymbol,
  canIncludeBindAndCheckDiagnostics,
  canJsonReportNoInputFiles,
  canProduceDiagnostics,
  canUsePropertyAccess,
  canWatchAffectingLocation,
  canWatchAtTypes,
  canWatchDirectoryOrFile,
  cartesianProduct,
  cast,
  chainBundle,
  chainDiagnosticMessages,
  changeAnyExtension,
  changeCompilerHostLikeToUseCache,
  changeExtension,
  changeFullExtension,
  changesAffectModuleResolution,
  changesAffectingProgramStructure,
  characterCodeToRegularExpressionFlag,
  childIsDecorated,
  classElementOrClassElementParameterIsDecorated,
  classHasClassThisAssignment,
  classHasDeclaredOrExplicitlyAssignedName,
  classHasExplicitlyAssignedName,
  classOrConstructorParameterIsDecorated,
  classicNameResolver,
  classifier,
  cleanExtendedConfigCache,
  clear,
  clearMap,
  clearSharedExtendedConfigFileWatcher,
  climbPastPropertyAccess,
  clone,
  cloneCompilerOptions,
  closeFileWatcher,
  closeFileWatcherOf,
  codefix,
  collapseTextChangeRangesAcrossMultipleVersions,
  collectExternalModuleInfo,
  combine,
  combinePaths,
  commandLineOptionOfCustomType,
  commentPragmas,
  commonOptionsWithBuild,
  compact,
  compareBooleans,
  compareDataObjects,
  compareDiagnostics,
  compareEmitHelpers,
  compareNumberOfDirectorySeparators,
  comparePaths,
  comparePathsCaseInsensitive,
  comparePathsCaseSensitive,
  comparePatternKeys,
  compareProperties,
  compareStringsCaseInsensitive,
  compareStringsCaseInsensitiveEslintCompatible,
  compareStringsCaseSensitive,
  compareStringsCaseSensitiveUI,
  compareTextSpans,
  compareValues,
  compilerOptionsAffectDeclarationPath,
  compilerOptionsAffectEmit,
  compilerOptionsAffectSemanticDiagnostics,
  compilerOptionsDidYouMeanDiagnostics,
  compilerOptionsIndicateEsModules,
  computeCommonSourceDirectoryOfFilenames,
  computeLineAndCharacterOfPosition,
  computeLineOfPosition,
  computeLineStarts,
  computePositionOfLineAndCharacter,
  computeSignatureWithDiagnostics,
  computeSuggestionDiagnostics,
  computedOptions,
  concatenate,
  concatenateDiagnosticMessageChains,
  consumesNodeCoreModules,
  contains,
  containsIgnoredPath,
  containsObjectRestOrSpread,
  containsParseError,
  containsPath,
  convertCompilerOptionsForTelemetry,
  convertCompilerOptionsFromJson,
  convertJsonOption,
  convertToBase64,
  convertToJson,
  convertToObject,
  convertToOptionsWithAbsolutePaths,
  convertToRelativePath,
  convertToTSConfig,
  convertTypeAcquisitionFromJson,
  copyComments,
  copyEntries,
  copyLeadingComments,
  copyProperties,
  copyTrailingAsLeadingComments,
  copyTrailingComments,
  couldStartTrivia,
  countWhere,
  createAbstractBuilder,
  createAccessorPropertyBackingField,
  createAccessorPropertyGetRedirector,
  createAccessorPropertySetRedirector,
  createBaseNodeFactory,
  createBinaryExpressionTrampoline,
  createBuilderProgram,
  createBuilderProgramUsingIncrementalBuildInfo,
  createBuilderStatusReporter,
  createCacheableExportInfoMap,
  createCachedDirectoryStructureHost,
  createClassifier,
  createCommentDirectivesMap,
  createCompilerDiagnostic,
  createCompilerDiagnosticForInvalidCustomType,
  createCompilerDiagnosticFromMessageChain,
  createCompilerHost,
  createCompilerHostFromProgramHost,
  createCompilerHostWorker,
  createDetachedDiagnostic,
  createDiagnosticCollection,
  createDiagnosticForFileFromMessageChain,
  createDiagnosticForNode,
  createDiagnosticForNodeArray,
  createDiagnosticForNodeArrayFromMessageChain,
  createDiagnosticForNodeFromMessageChain,
  createDiagnosticForNodeInSourceFile,
  createDiagnosticForRange,
  createDiagnosticMessageChainFromDiagnostic,
  createDiagnosticReporter,
  createDocumentPositionMapper,
  createDocumentRegistry,
  createDocumentRegistryInternal,
  createEmitAndSemanticDiagnosticsBuilderProgram,
  createEmitHelperFactory,
  createEmptyExports,
  createEvaluator,
  createExpressionForJsxElement,
  createExpressionForJsxFragment,
  createExpressionForObjectLiteralElementLike,
  createExpressionForPropertyName,
  createExpressionFromEntityName,
  createExternalHelpersImportDeclarationIfNeeded,
  createFileDiagnostic,
  createFileDiagnosticFromMessageChain,
  createFlowNode,
  createForOfBindingStatement,
  createFutureSourceFile,
  createGetCanonicalFileName,
  createGetIsolatedDeclarationErrors,
  createGetSourceFile,
  createGetSymbolAccessibilityDiagnosticForNode,
  createGetSymbolAccessibilityDiagnosticForNodeName,
  createGetSymbolWalker,
  createIncrementalCompilerHost,
  createIncrementalProgram,
  createJsxFactoryExpression,
  createLanguageService,
  createLanguageServiceSourceFile,
  createMemberAccessForPropertyName,
  createModeAwareCache,
  createModeAwareCacheKey,
  createModeMismatchDetails,
  createModuleNotFoundChain,
  createModuleResolutionCache,
  createModuleResolutionLoader,
  createModuleResolutionLoaderUsingGlobalCache,
  createModuleSpecifierResolutionHost,
  createMultiMap,
  createNameResolver,
  createNodeConverters,
  createNodeFactory,
  createOptionNameMap,
  createOverload,
  createPackageJsonImportFilter,
  createPackageJsonInfo,
  createParenthesizerRules,
  createPatternMatcher,
  createPrinter,
  createPrinterWithDefaults,
  createPrinterWithRemoveComments,
  createPrinterWithRemoveCommentsNeverAsciiEscape,
  createPrinterWithRemoveCommentsOmitTrailingSemicolon,
  createProgram,
  createProgramHost,
  createPropertyNameNodeForIdentifierOrLiteral,
  createQueue,
  createRange,
  createRedirectedBuilderProgram,
  createResolutionCache,
  createRuntimeTypeSerializer,
  createScanner,
  createSemanticDiagnosticsBuilderProgram,
  createSet,
  createSolutionBuilder,
  createSolutionBuilderHost,
  createSolutionBuilderWithWatch,
  createSolutionBuilderWithWatchHost,
  createSortedArray,
  createSourceFile,
  createSourceMapGenerator,
  createSourceMapSource,
  createSuperAccessVariableStatement,
  createSymbolTable,
  createSymlinkCache,
  createSyntacticTypeNodeBuilder,
  createSystemWatchFunctions,
  createTextChange,
  createTextChangeFromStartLength,
  createTextChangeRange,
  createTextRangeFromNode,
  createTextRangeFromSpan,
  createTextSpan,
  createTextSpanFromBounds,
  createTextSpanFromNode,
  createTextSpanFromRange,
  createTextSpanFromStringLiteralLikeContent,
  createTextWriter,
  createTokenRange,
  createTypeChecker,
  createTypeReferenceDirectiveResolutionCache,
  createTypeReferenceResolutionLoader,
  createWatchCompilerHost,
  createWatchCompilerHostOfConfigFile,
  createWatchCompilerHostOfFilesAndCompilerOptions,
  createWatchFactory,
  createWatchHost,
  createWatchProgram,
  createWatchStatusReporter,
  createWriteFileMeasuringIO,
  declarationNameToString,
  decodeMappings,
  decodedTextSpanIntersectsWith,
  deduplicate,
  defaultInitCompilerOptions,
  defaultMaximumTruncationLength,
  diagnosticCategoryName,
  diagnosticToString,
  diagnosticsEqualityComparer,
  directoryProbablyExists,
  directorySeparator,
  displayPart,
  displayPartsToString,
  disposeEmitNodes,
  documentSpansEqual,
  dumpTracingLegend,
  elementAt,
  elideNodes,
  emitDetachedComments,
  emitFiles,
  emitFilesAndReportErrors,
  emitFilesAndReportErrorsAndGetExitStatus,
  emitModuleKindIsNonNodeESM,
  emitNewLineBeforeLeadingCommentOfPosition,
  emitResolverSkipsTypeChecking,
  emitSkippedWithNoDiagnostics,
  emptyArray,
  emptyFileSystemEntries,
  emptyMap,
  emptyOptions,
  endsWith,
  ensurePathIsNonModuleName,
  ensureScriptKind,
  ensureTrailingDirectorySeparator,
  entityNameToString,
  enumerateInsertsAndDeletes,
  equalOwnProperties,
  equateStringsCaseInsensitive,
  equateStringsCaseSensitive,
  equateValues,
  escapeJsxAttributeString,
  escapeLeadingUnderscores,
  escapeNonAsciiString,
  escapeSnippetText,
  escapeString,
  escapeTemplateSubstitution,
  evaluatorResult,
  every,
  executeCommandLine,
  expandPreOrPostfixIncrementOrDecrementExpression,
  explainFiles,
  explainIfFileIsRedirectAndImpliedFormat,
  exportAssignmentIsAlias,
  expressionResultIsUnused,
  extend,
  extensionFromPath,
  extensionIsTS,
  extensionsNotSupportingExtensionlessResolution,
  externalHelpersModuleNameText,
  factory,
  fileContainsPackageImport,
  fileExtensionIs,
  fileExtensionIsOneOf,
  fileIncludeReasonToDiagnostics,
  fileShouldUseJavaScriptRequire,
  filter,
  filterMutate,
  filterSemanticDiagnostics,
  find,
  findAncestor,
  findBestPatternMatch,
  findChildOfKind,
  findComputedPropertyNameCacheAssignment,
  findConfigFile,
  findConstructorDeclaration,
  findContainingList,
  findDiagnosticForNode,
  findFirstNonJsxWhitespaceToken,
  findIndex,
  findLast,
  findLastIndex,
  findListItemInfo,
  findModifier,
  findNextToken,
  findPackageJson,
  findPackageJsons,
  findPrecedingMatchingToken,
  findPrecedingToken,
  findSuperStatementIndexPath,
  findTokenOnLeftOfPosition,
  findUseStrictPrologue,
  first,
  firstDefined,
  firstDefinedIterator,
  firstIterator,
  firstOrOnly,
  firstOrUndefined,
  firstOrUndefinedIterator,
  fixupCompilerOptions,
  flatMap,
  flatMapIterator,
  flatMapToMutable,
  flatten,
  flattenCommaList,
  flattenDestructuringAssignment,
  flattenDestructuringBinding,
  flattenDiagnosticMessageText,
  forEach,
  forEachAncestor,
  forEachAncestorDirectory,
  forEachChild,
  forEachChildRecursively,
  forEachEmittedFile,
  forEachEnclosingBlockScopeContainer,
  forEachEntry,
  forEachExternalModuleToImportFrom,
  forEachImportClauseDeclaration,
  forEachKey,
  forEachLeadingCommentRange,
  forEachNameInAccessChainWalkingLeft,
  forEachNameOfDefaultExport,
  forEachPropertyAssignment,
  forEachResolvedProjectReference,
  forEachReturnStatement,
  forEachRight,
  forEachTrailingCommentRange,
  forEachTsConfigPropArray,
  forEachUnique,
  forEachYieldExpression,
  formatColorAndReset,
  formatDiagnostic,
  formatDiagnostics,
  formatDiagnosticsWithColorAndContext,
  formatGeneratedName,
  formatGeneratedNamePart,
  formatLocation,
  formatMessage,
  formatStringFromArgs,
  formatting,
  generateDjb2Hash,
  generateTSConfig,
  getAdjustedReferenceLocation,
  getAdjustedRenameLocation,
  getAliasDeclarationFromName,
  getAllAccessorDeclarations,
  getAllDecoratorsOfClass,
  getAllDecoratorsOfClassElement,
  getAllJSDocTags,
  getAllJSDocTagsOfKind,
  getAllKeys,
  getAllProjectOutputs,
  getAllSuperTypeNodes,
  getAllowJSCompilerOption,
  getAllowSyntheticDefaultImports,
  getAncestor,
  getAnyExtensionFromPath,
  getAreDeclarationMapsEnabled,
  getAssignedExpandoInitializer,
  getAssignedName,
  getAssignmentDeclarationKind,
  getAssignmentDeclarationPropertyAccessKind,
  getAssignmentTargetKind,
  getAutomaticTypeDirectiveNames,
  getBaseFileName,
  getBinaryOperatorPrecedence,
  getBuildInfo,
  getBuildInfoFileVersionMap,
  getBuildInfoText,
  getBuildOrderFromAnyBuildOrder,
  getBuilderCreationParameters,
  getBuilderFileEmit,
  getCanonicalDiagnostic,
  getCheckFlags,
  getClassExtendsHeritageElement,
  getClassLikeDeclarationOfSymbol,
  getCombinedLocalAndExportSymbolFlags,
  getCombinedModifierFlags,
  getCombinedNodeFlags,
  getCombinedNodeFlagsAlwaysIncludeJSDoc,
  getCommentRange,
  getCommonSourceDirectory,
  getCommonSourceDirectoryOfConfig,
  getCompilerOptionValue,
  getCompilerOptionsDiffValue,
  getConditions,
  getConfigFileParsingDiagnostics,
  getConstantValue,
  getContainerFlags,
  getContainerNode,
  getContainingClass,
  getContainingClassExcludingClassDecorators,
  getContainingClassStaticBlock,
  getContainingFunction,
  getContainingFunctionDeclaration,
  getContainingFunctionOrClassStaticBlock,
  getContainingNodeArray,
  getContainingObjectLiteralElement,
  getContextualTypeFromParent,
  getContextualTypeFromParentOrAncestorTypeNode,
  getDeclarationDiagnostics,
  getDeclarationEmitExtensionForPath,
  getDeclarationEmitOutputFilePath,
  getDeclarationEmitOutputFilePathWorker,
  getDeclarationFileExtension,
  getDeclarationFromName,
  getDeclarationModifierFlagsFromSymbol,
  getDeclarationOfKind,
  getDeclarationsOfKind,
  getDeclaredExpandoInitializer,
  getDecorators,
  getDefaultCompilerOptions,
  getDefaultFormatCodeSettings,
  getDefaultLibFileName,
  getDefaultLibFilePath,
  getDefaultLikeExportInfo,
  getDefaultLikeExportNameFromDeclaration,
  getDefaultResolutionModeForFileWorker,
  getDiagnosticText,
  getDiagnosticsWithinSpan,
  getDirectoryPath,
  getDirectoryToWatchFailedLookupLocation,
  getDirectoryToWatchFailedLookupLocationFromTypeRoot,
  getDocumentPositionMapper,
  getDocumentSpansEqualityComparer,
  getESModuleInterop,
  getEditsForFileRename,
  getEffectiveBaseTypeNode,
  getEffectiveConstraintOfTypeParameter,
  getEffectiveContainerForJSDocTemplateTag,
  getEffectiveImplementsTypeNodes,
  getEffectiveInitializer,
  getEffectiveJSDocHost,
  getEffectiveModifierFlags,
  getEffectiveModifierFlagsAlwaysIncludeJSDoc,
  getEffectiveModifierFlagsNoCache,
  getEffectiveReturnTypeNode,
  getEffectiveSetAccessorTypeAnnotationNode,
  getEffectiveTypeAnnotationNode,
  getEffectiveTypeParameterDeclarations,
  getEffectiveTypeRoots,
  getElementOrPropertyAccessArgumentExpressionOrName,
  getElementOrPropertyAccessName,
  getElementsOfBindingOrAssignmentPattern,
  getEmitDeclarations,
  getEmitFlags,
  getEmitHelpers,
  getEmitModuleDetectionKind,
  getEmitModuleFormatOfFileWorker,
  getEmitModuleKind,
  getEmitModuleResolutionKind,
  getEmitScriptTarget,
  getEmitStandardClassFields,
  getEnclosingBlockScopeContainer,
  getEnclosingContainer,
  getEncodedSemanticClassifications,
  getEncodedSyntacticClassifications,
  getEndLinePosition,
  getEntityNameFromTypeNode,
  getEntrypointsFromPackageJsonInfo,
  getErrorCountForSummary,
  getErrorSpanForNode,
  getErrorSummaryText,
  getEscapedTextOfIdentifierOrLiteral,
  getEscapedTextOfJsxAttributeName,
  getEscapedTextOfJsxNamespacedName,
  getExpandoInitializer,
  getExportAssignmentExpression,
  getExportInfoMap,
  getExportNeedsImportStarHelper,
  getExpressionAssociativity,
  getExpressionPrecedence,
  getExternalHelpersModuleName,
  getExternalModuleImportEqualsDeclarationExpression,
  getExternalModuleName,
  getExternalModuleNameFromDeclaration,
  getExternalModuleNameFromPath,
  getExternalModuleNameLiteral,
  getExternalModuleRequireArgument,
  getFallbackOptions,
  getFileEmitOutput,
  getFileMatcherPatterns,
  getFileNamesFromConfigSpecs,
  getFileWatcherEventKind,
  getFilesInErrorForSummary,
  getFirstConstructorWithBody,
  getFirstIdentifier,
  getFirstNonSpaceCharacterPosition,
  getFirstProjectOutput,
  getFixableErrorSpanExpression,
  getFormatCodeSettingsForWriting,
  getFullWidth,
  getFunctionFlags,
  getHeritageClause,
  getHostSignatureFromJSDoc,
  getIdentifierAutoGenerate,
  getIdentifierGeneratedImportReference,
  getIdentifierTypeArguments,
  getImmediatelyInvokedFunctionExpression,
  getImpliedNodeFormatForEmitWorker,
  getImpliedNodeFormatForFile,
  getImpliedNodeFormatForFileWorker,
  getImportNeedsImportDefaultHelper,
  getImportNeedsImportStarHelper,
  getIndentString,
  getInferredLibraryNameResolveFrom,
  getInitializedVariables,
  getInitializerOfBinaryExpression,
  getInitializerOfBindingOrAssignmentElement,
  getInterfaceBaseTypeNodes,
  getInternalEmitFlags,
  getInvokedExpression,
  getIsFileExcluded,
  getIsolatedModules,
  getJSDocAugmentsTag,
  getJSDocClassTag,
  getJSDocCommentRanges,
  getJSDocCommentsAndTags,
  getJSDocDeprecatedTag,
  getJSDocDeprecatedTagNoCache,
  getJSDocEnumTag,
  getJSDocHost,
  getJSDocImplementsTags,
  getJSDocOverloadTags,
  getJSDocOverrideTagNoCache,
  getJSDocParameterTags,
  getJSDocParameterTagsNoCache,
  getJSDocPrivateTag,
  getJSDocPrivateTagNoCache,
  getJSDocProtectedTag,
  getJSDocProtectedTagNoCache,
  getJSDocPublicTag,
  getJSDocPublicTagNoCache,
  getJSDocReadonlyTag,
  getJSDocReadonlyTagNoCache,
  getJSDocReturnTag,
  getJSDocReturnType,
  getJSDocRoot,
  getJSDocSatisfiesExpressionType,
  getJSDocSatisfiesTag,
  getJSDocTags,
  getJSDocTemplateTag,
  getJSDocThisTag,
  getJSDocType,
  getJSDocTypeAliasName,
  getJSDocTypeAssertionType,
  getJSDocTypeParameterDeclarations,
  getJSDocTypeParameterTags,
  getJSDocTypeParameterTagsNoCache,
  getJSDocTypeTag,
  getJSXImplicitImportBase,
  getJSXRuntimeImport,
  getJSXTransformEnabled,
  getKeyForCompilerOptions,
  getLanguageVariant,
  getLastChild,
  getLeadingCommentRanges,
  getLeadingCommentRangesOfNode,
  getLeftmostAccessExpression,
  getLeftmostExpression,
  getLibraryNameFromLibFileName,
  getLineAndCharacterOfPosition,
  getLineInfo,
  getLineOfLocalPosition,
  getLineStartPositionForPosition,
  getLineStarts,
  getLinesBetweenPositionAndNextNonWhitespaceCharacter,
  getLinesBetweenPositionAndPrecedingNonWhitespaceCharacter,
  getLinesBetweenPositions,
  getLinesBetweenRangeEndAndRangeStart,
  getLinesBetweenRangeEndPositions,
  getLiteralText,
  getLocalNameForExternalImport,
  getLocalSymbolForExportDefault,
  getLocaleSpecificMessage,
  getLocaleTimeString,
  getMappedContextSpan,
  getMappedDocumentSpan,
  getMappedLocation,
  getMatchedFileSpec,
  getMatchedIncludeSpec,
  getMeaningFromDeclaration,
  getMeaningFromLocation,
  getMembersOfDeclaration,
  getModeForFileReference,
  getModeForResolutionAtIndex,
  getModeForUsageLocation,
  getModifiedTime,
  getModifiers,
  getModuleInstanceState,
  getModuleNameStringLiteralAt,
  getModuleSpecifierEndingPreference,
  getModuleSpecifierResolverHost,
  getNameForExportedSymbol,
  getNameFromImportAttribute,
  getNameFromIndexInfo,
  getNameFromPropertyName,
  getNameOfAccessExpression,
  getNameOfCompilerOptionValue,
  getNameOfDeclaration,
  getNameOfExpando,
  getNameOfJSDocTypedef,
  getNameOfScriptTarget,
  getNameOrArgument,
  getNameTable,
  getNamespaceDeclarationNode,
  getNewLineCharacter,
  getNewLineKind,
  getNewLineOrDefaultFromHost,
  getNewTargetContainer,
  getNextJSDocCommentLocation,
  getNodeChildren,
  getNodeForGeneratedName,
  getNodeId,
  getNodeKind,
  getNodeModifiers,
  getNodeModulePathParts,
  getNonAssignedNameOfDeclaration,
  getNonAssignmentOperatorForCompoundAssignment,
  getNonAugmentationDeclaration,
  getNonDecoratorTokenPosOfNode,
  getNonIncrementalBuildInfoRoots,
  getNonModifierTokenPosOfNode,
  getNormalizedAbsolutePath,
  getNormalizedAbsolutePathWithoutRoot,
  getNormalizedPathComponents,
  getObjectFlags,
  getOperatorAssociativity,
  getOperatorPrecedence,
  getOptionFromName,
  getOptionsForLibraryResolution,
  getOptionsNameMap,
  getOrCreateEmitNode,
  getOrUpdate,
  getOriginalNode,
  getOriginalNodeId,
  getOutputDeclarationFileName,
  getOutputDeclarationFileNameWorker,
  getOutputExtension,
  getOutputFileNames,
  getOutputJSFileNameWorker,
  getOutputPathsFor,
  getOwnEmitOutputFilePath,
  getOwnKeys,
  getOwnValues,
  getPackageJsonTypesVersionsPaths,
  getPackageNameFromTypesPackageName,
  getPackageScopeForPath,
  getParameterSymbolFromJSDoc,
  getParentNodeInSpan,
  getParseTreeNode,
  getParsedCommandLineOfConfigFile,
  getPathComponents,
  getPathFromPathComponents,
  getPathUpdater,
  getPathsBasePath,
  getPatternFromSpec,
  getPendingEmitKindWithSeen,
  getPositionOfLineAndCharacter,
  getPossibleGenericSignatures,
  getPossibleOriginalInputExtensionForExtension,
  getPossibleTypeArgumentsInfo,
  getPreEmitDiagnostics,
  getPrecedingNonSpaceCharacterPosition,
  getPrivateIdentifier,
  getProperties,
  getProperty,
  getPropertyArrayElementValue,
  getPropertyAssignmentAliasLikeExpression,
  getPropertyNameForPropertyNameNode,
  getPropertyNameFromType,
  getPropertyNameOfBindingOrAssignmentElement,
  getPropertySymbolFromBindingElement,
  getPropertySymbolsFromContextualType,
  getQuoteFromPreference,
  getQuotePreference,
  getRangesWhere,
  getRefactorContextSpan,
  getReferencedFileLocation,
  getRegexFromPattern,
  getRegularExpressionForWildcard,
  getRegularExpressionsForWildcards,
  getRelativePathFromDirectory,
  getRelativePathFromFile,
  getRelativePathToDirectoryOrUrl,
  getRenameLocation,
  getReplacementSpanForContextToken,
  getResolutionDiagnostic,
  getResolutionModeOverride,
  getResolveJsonModule,
  getResolvePackageJsonExports,
  getResolvePackageJsonImports,
  getResolvedExternalModuleName,
  getResolvedModuleFromResolution,
  getResolvedTypeReferenceDirectiveFromResolution,
  getRestIndicatorOfBindingOrAssignmentElement,
  getRestParameterElementType,
  getRightMostAssignedExpression,
  getRootDeclaration,
  getRootDirectoryOfResolutionCache,
  getRootLength,
  getScriptKind,
  getScriptKindFromFileName,
  getScriptTargetFeatures,
  getSelectedEffectiveModifierFlags,
  getSelectedSyntacticModifierFlags,
  getSemanticClassifications,
  getSemanticJsxChildren,
  getSetAccessorTypeAnnotationNode,
  getSetAccessorValueParameter,
  getSetExternalModuleIndicator,
  getShebang,
  getSingleVariableOfVariableStatement,
  getSnapshotText,
  getSnippetElement,
  getSourceFileOfModule,
  getSourceFileOfNode,
  getSourceFilePathInNewDir,
  getSourceFileVersionAsHashFromText,
  getSourceFilesToEmit,
  getSourceMapRange,
  getSourceMapper,
  getSourceTextOfNodeFromSourceFile,
  getSpanOfTokenAtPosition,
  getSpellingSuggestion,
  getStartPositionOfLine,
  getStartPositionOfRange,
  getStartsOnNewLine,
  getStaticPropertiesAndClassStaticBlock,
  getStrictOptionValue,
  getStringComparer,
  getSubPatternFromSpec,
  getSuperCallFromStatement,
  getSuperContainer,
  getSupportedCodeFixes,
  getSupportedExtensions,
  getSupportedExtensionsWithJsonIfResolveJsonModule,
  getSwitchedType,
  getSymbolId,
  getSymbolNameForPrivateIdentifier,
  getSymbolTarget,
  getSyntacticClassifications,
  getSyntacticModifierFlags,
  getSyntacticModifierFlagsNoCache,
  getSynthesizedDeepClone,
  getSynthesizedDeepCloneWithReplacements,
  getSynthesizedDeepClones,
  getSynthesizedDeepClonesWithReplacements,
  getSyntheticLeadingComments,
  getSyntheticTrailingComments,
  getTargetLabel,
  getTargetOfBindingOrAssignmentElement,
  getTemporaryModuleResolutionState,
  getTextOfConstantValue,
  getTextOfIdentifierOrLiteral,
  getTextOfJSDocComment,
  getTextOfJsxAttributeName,
  getTextOfJsxNamespacedName,
  getTextOfNode,
  getTextOfNodeFromSourceText,
  getTextOfPropertyName,
  getThisContainer,
  getThisParameter,
  getTokenAtPosition,
  getTokenPosOfNode,
  getTokenSourceMapRange,
  getTouchingPropertyName,
  getTouchingToken,
  getTrailingCommentRanges,
  getTrailingSemicolonDeferringWriter,
  getTransformers,
  getTsBuildInfoEmitOutputFilePath,
  getTsConfigObjectLiteralExpression,
  getTsConfigPropArrayElementValue,
  getTypeAnnotationNode,
  getTypeArgumentOrTypeParameterList,
  getTypeKeywordOfTypeOnlyImport,
  getTypeNode,
  getTypeNodeIfAccessible,
  getTypeParameterFromJsDoc,
  getTypeParameterOwner,
  getTypesPackageName,
  getUILocale,
  getUniqueName,
  getUniqueSymbolId,
  getUseDefineForClassFields,
  getWatchErrorSummaryDiagnosticMessage,
  getWatchFactory,
  group,
  groupBy,
  guessIndentation,
  handleNoEmitOptions,
  handleWatchOptionsConfigDirTemplateSubstitution,
  hasAbstractModifier,
  hasAccessorModifier,
  hasAmbientModifier,
  hasChangesInResolutions,
  hasContextSensitiveParameters,
  hasDecorators,
  hasDocComment,
  hasDynamicName,
  hasEffectiveModifier,
  hasEffectiveModifiers,
  hasEffectiveReadonlyModifier,
  hasExtension,
  hasImplementationTSFileExtension,
  hasIndexSignature,
  hasInferredType,
  hasInitializer,
  hasInvalidEscape,
  hasJSDocNodes,
  hasJSDocParameterTags,
  hasJSFileExtension,
  hasJsonModuleEmitEnabled,
  hasOnlyExpressionInitializer,
  hasOverrideModifier,
  hasPossibleExternalModuleReference,
  hasProperty,
  hasPropertyAccessExpressionWithName,
  hasQuestionToken,
  hasRecordedExternalHelpers,
  hasResolutionModeOverride,
  hasRestParameter,
  hasScopeMarker,
  hasStaticModifier,
  hasSyntacticModifier,
  hasSyntacticModifiers,
  hasTSFileExtension,
  hasTabstop,
  hasTrailingDirectorySeparator,
  hasType,
  hasTypeArguments,
  hasZeroOrOneAsteriskCharacter,
  hostGetCanonicalFileName,
  hostUsesCaseSensitiveFileNames,
  idText,
  identifierIsThisKeyword,
  identifierToKeywordKind,
  identity,
  identitySourceMapConsumer,
  ignoreSourceNewlines,
  ignoredPaths,
  importFromModuleSpecifier,
  importSyntaxAffectsModuleResolution,
  indexOfAnyCharCode,
  indexOfNode,
  indicesOf,
  inferredTypesContainingFile,
  injectClassNamedEvaluationHelperBlockIfMissing,
  injectClassThisAssignmentIfMissing,
  insertImports,
  insertSorted,
  insertStatementAfterCustomPrologue,
  insertStatementAfterStandardPrologue,
  insertStatementsAfterCustomPrologue,
  insertStatementsAfterStandardPrologue,
  intersperse,
  intrinsicTagNameToString,
  introducesArgumentsExoticObject,
  inverseJsxOptionMap,
  isAbstractConstructorSymbol,
  isAbstractModifier,
  isAccessExpression,
  isAccessibilityModifier,
  isAccessor,
  isAccessorModifier,
  isAliasableExpression,
  isAmbientModule,
  isAmbientPropertyDeclaration,
  isAnyDirectorySeparator,
  isAnyImportOrBareOrAccessedRequire,
  isAnyImportOrReExport,
  isAnyImportOrRequireStatement,
  isAnyImportSyntax,
  isAnySupportedFileExtension,
  isApplicableVersionedTypesKey,
  isArgumentExpressionOfElementAccess,
  isArray,
  isArrayBindingElement,
  isArrayBindingOrAssignmentElement,
  isArrayBindingOrAssignmentPattern,
  isArrayBindingPattern,
  isArrayLiteralExpression,
  isArrayLiteralOrObjectLiteralDestructuringPattern,
  isArrayTypeNode,
  isArrowFunction,
  isAsExpression,
  isAssertClause,
  isAssertEntry,
  isAssertionExpression,
  isAssertsKeyword,
  isAssignmentDeclaration,
  isAssignmentExpression,
  isAssignmentOperator,
  isAssignmentPattern,
  isAssignmentTarget,
  isAsteriskToken,
  isAsyncFunction,
  isAsyncModifier,
  isAutoAccessorPropertyDeclaration,
  isAwaitExpression,
  isAwaitKeyword,
  isBigIntLiteral,
  isBinaryExpression,
  isBinaryLogicalOperator,
  isBinaryOperatorToken,
  isBindableObjectDefinePropertyCall,
  isBindableStaticAccessExpression,
  isBindableStaticElementAccessExpression,
  isBindableStaticNameExpression,
  isBindingElement,
  isBindingElementOfBareOrAccessedRequire,
  isBindingName,
  isBindingOrAssignmentElement,
  isBindingOrAssignmentPattern,
  isBindingPattern,
  isBlock,
  isBlockLike,
  isBlockOrCatchScoped,
  isBlockScope,
  isBlockScopedContainerTopLevel,
  isBooleanLiteral,
  isBreakOrContinueStatement,
  isBreakStatement,
  isBuild,
  isBuildInfoFile,
  isBuilderProgram,
  isBundle,
  isCallChain,
  isCallExpression,
  isCallExpressionTarget,
  isCallLikeExpression,
  isCallLikeOrFunctionLikeExpression,
  isCallOrNewExpression,
  isCallOrNewExpressionTarget,
  isCallSignatureDeclaration,
  isCallToHelper,
  isCaseBlock,
  isCaseClause,
  isCaseKeyword,
  isCaseOrDefaultClause,
  isCatchClause,
  isCatchClauseVariableDeclaration,
  isCatchClauseVariableDeclarationOrBindingElement,
  isCheckJsEnabledForFile,
  isCircularBuildOrder,
  isClassDeclaration,
  isClassElement,
  isClassExpression,
  isClassInstanceProperty,
  isClassLike,
  isClassMemberModifier,
  isClassNamedEvaluationHelperBlock,
  isClassOrTypeElement,
  isClassStaticBlockDeclaration,
  isClassThisAssignmentBlock,
  isColonToken,
  isCommaExpression,
  isCommaListExpression,
  isCommaSequence,
  isCommaToken,
  isComment,
  isCommonJsExportPropertyAssignment,
  isCommonJsExportedExpression,
  isCompoundAssignment,
  isComputedNonLiteralName,
  isComputedPropertyName,
  isConciseBody,
  isConditionalExpression,
  isConditionalTypeNode,
  isConstAssertion,
  isConstTypeReference,
  isConstructSignatureDeclaration,
  isConstructorDeclaration,
  isConstructorTypeNode,
  isContextualKeyword,
  isContinueStatement,
  isCustomPrologue,
  isDebuggerStatement,
  isDeclaration,
  isDeclarationBindingElement,
  isDeclarationFileName,
  isDeclarationName,
  isDeclarationNameOfEnumOrNamespace,
  isDeclarationReadonly,
  isDeclarationStatement,
  isDeclarationWithTypeParameterChildren,
  isDeclarationWithTypeParameters,
  isDecorator,
  isDecoratorTarget,
  isDefaultClause,
  isDefaultImport,
  isDefaultModifier,
  isDefaultedExpandoInitializer,
  isDeleteExpression,
  isDeleteTarget,
  isDeprecatedDeclaration,
  isDestructuringAssignment,
  isDiskPathRoot,
  isDoStatement,
  isDocumentRegistryEntry,
  isDotDotDotToken,
  isDottedName,
  isDynamicName,
  isEffectiveExternalModule,
  isEffectiveStrictModeSourceFile,
  isElementAccessChain,
  isElementAccessExpression,
  isEmittedFileOfProgram,
  isEmptyArrayLiteral,
  isEmptyBindingElement,
  isEmptyBindingPattern,
  isEmptyObjectLiteral,
  isEmptyStatement,
  isEmptyStringLiteral,
  isEntityName,
  isEntityNameExpression,
  isEnumConst,
  isEnumDeclaration,
  isEnumMember,
  isEqualityOperatorKind,
  isEqualsGreaterThanToken,
  isExclamationToken,
  isExcludedFile,
  isExclusivelyTypeOnlyImportOrExport,
  isExpandoPropertyDeclaration,
  isExportAssignment,
  isExportDeclaration,
  isExportModifier,
  isExportName,
  isExportNamespaceAsDefaultDeclaration,
  isExportOrDefaultModifier,
  isExportSpecifier,
  isExportsIdentifier,
  isExportsOrModuleExportsOrAlias,
  isExpression,
  isExpressionNode,
  isExpressionOfExternalModuleImportEqualsDeclaration,
  isExpressionOfOptionalChainRoot,
  isExpressionStatement,
  isExpressionWithTypeArguments,
  isExpressionWithTypeArgumentsInClassExtendsClause,
  isExternalModule,
  isExternalModuleAugmentation,
  isExternalModuleImportEqualsDeclaration,
  isExternalModuleIndicator,
  isExternalModuleNameRelative,
  isExternalModuleReference,
  isExternalModuleSymbol,
  isExternalOrCommonJsModule,
  isFileLevelReservedGeneratedIdentifier,
  isFileLevelUniqueName,
  isFileProbablyExternalModule,
  isFirstDeclarationOfSymbolParameter,
  isFixablePromiseHandler,
  isForInOrOfStatement,
  isForInStatement,
  isForInitializer,
  isForOfStatement,
  isForStatement,
  isFullSourceFile,
  isFunctionBlock,
  isFunctionBody,
  isFunctionDeclaration,
  isFunctionExpression,
  isFunctionExpressionOrArrowFunction,
  isFunctionLike,
  isFunctionLikeDeclaration,
  isFunctionLikeKind,
  isFunctionLikeOrClassStaticBlockDeclaration,
  isFunctionOrConstructorTypeNode,
  isFunctionOrModuleBlock,
  isFunctionSymbol,
  isFunctionTypeNode,
  isGeneratedIdentifier,
  isGeneratedPrivateIdentifier,
  isGetAccessor,
  isGetAccessorDeclaration,
  isGetOrSetAccessorDeclaration,
  isGlobalScopeAugmentation,
  isGlobalSourceFile,
  isGrammarError,
  isHeritageClause,
  isHoistedFunction,
  isHoistedVariableStatement,
  isIdentifier,
  isIdentifierANonContextualKeyword,
  isIdentifierName,
  isIdentifierOrThisTypeNode,
  isIdentifierPart,
  isIdentifierStart,
  isIdentifierText,
  isIdentifierTypePredicate,
  isIdentifierTypeReference,
  isIfStatement,
  isIgnoredFileFromWildCardWatching,
  isImplicitGlob,
  isImportAttribute,
  isImportAttributeName,
  isImportAttributes,
  isImportCall,
  isImportClause,
  isImportDeclaration,
  isImportEqualsDeclaration,
  isImportKeyword,
  isImportMeta,
  isImportOrExportSpecifier,
  isImportOrExportSpecifierName,
  isImportSpecifier,
  isImportTypeAssertionContainer,
  isImportTypeNode,
  isImportableFile,
  isInComment,
  isInCompoundLikeAssignment,
  isInExpressionContext,
  isInJSDoc,
  isInJSFile,
  isInJSXText,
  isInJsonFile,
  isInNonReferenceComment,
  isInReferenceComment,
  isInRightSideOfInternalImportEqualsDeclaration,
  isInString,
  isInTemplateString,
  isInTopLevelContext,
  isInTypeQuery,
  isIncrementalBuildInfo,
  isIncrementalBundleEmitBuildInfo,
  isIncrementalCompilation,
  isIndexSignatureDeclaration,
  isIndexedAccessTypeNode,
  isInferTypeNode,
  isInfinityOrNaNString,
  isInitializedProperty,
  isInitializedVariable,
  isInsideJsxElement,
  isInsideJsxElementOrAttribute,
  isInsideNodeModules,
  isInsideTemplateLiteral,
  isInstanceOfExpression,
  isInstantiatedModule,
  isInterfaceDeclaration,
  isInternalDeclaration,
  isInternalModuleImportEqualsDeclaration,
  isInternalName,
  isIntersectionTypeNode,
  isIntrinsicJsxName,
  isIterationStatement,
  isJSDoc,
  isJSDocAllType,
  isJSDocAugmentsTag,
  isJSDocAuthorTag,
  isJSDocCallbackTag,
  isJSDocClassTag,
  isJSDocCommentContainingNode,
  isJSDocConstructSignature,
  isJSDocDeprecatedTag,
  isJSDocEnumTag,
  isJSDocFunctionType,
  isJSDocImplementsTag,
  isJSDocImportTag,
  isJSDocIndexSignature,
  isJSDocLikeText,
  isJSDocLink,
  isJSDocLinkCode,
  isJSDocLinkLike,
  isJSDocLinkPlain,
  isJSDocMemberName,
  isJSDocNameReference,
  isJSDocNamepathType,
  isJSDocNamespaceBody,
  isJSDocNode,
  isJSDocNonNullableType,
  isJSDocNullableType,
  isJSDocOptionalParameter,
  isJSDocOptionalType,
  isJSDocOverloadTag,
  isJSDocOverrideTag,
  isJSDocParameterTag,
  isJSDocPrivateTag,
  isJSDocPropertyLikeTag,
  isJSDocPropertyTag,
  isJSDocProtectedTag,
  isJSDocPublicTag,
  isJSDocReadonlyTag,
  isJSDocReturnTag,
  isJSDocSatisfiesExpression,
  isJSDocSatisfiesTag,
  isJSDocSeeTag,
  isJSDocSignature,
  isJSDocTag,
  isJSDocTemplateTag,
  isJSDocThisTag,
  isJSDocThrowsTag,
  isJSDocTypeAlias,
  isJSDocTypeAssertion,
  isJSDocTypeExpression,
  isJSDocTypeLiteral,
  isJSDocTypeTag,
  isJSDocTypedefTag,
  isJSDocUnknownTag,
  isJSDocUnknownType,
  isJSDocVariadicType,
  isJSXTagName,
  isJsonEqual,
  isJsonSourceFile,
  isJsxAttribute,
  isJsxAttributeLike,
  isJsxAttributeName,
  isJsxAttributes,
  isJsxChild,
  isJsxClosingElement,
  isJsxClosingFragment,
  isJsxElement,
  isJsxExpression,
  isJsxFragment,
  isJsxNamespacedName,
  isJsxOpeningElement,
  isJsxOpeningFragment,
  isJsxOpeningLikeElement,
  isJsxOpeningLikeElementTagName,
  isJsxSelfClosingElement,
  isJsxSpreadAttribute,
  isJsxTagNameExpression,
  isJsxText,
  isJumpStatementTarget,
  isKeyword,
  isKeywordOrPunctuation,
  isKnownSymbol,
  isLabelName,
  isLabelOfLabeledStatement,
  isLabeledStatement,
  isLateVisibilityPaintedStatement,
  isLeftHandSideExpression,
  isLet,
  isLineBreak,
  isLiteralComputedPropertyDeclarationName,
  isLiteralExpression,
  isLiteralExpressionOfObject,
  isLiteralImportTypeNode,
  isLiteralKind,
  isLiteralNameOfPropertyDeclarationOrIndexAccess,
  isLiteralTypeLiteral,
  isLiteralTypeNode,
  isLocalName,
  isLogicalOperator,
  isLogicalOrCoalescingAssignmentExpression,
  isLogicalOrCoalescingAssignmentOperator,
  isLogicalOrCoalescingBinaryExpression,
  isLogicalOrCoalescingBinaryOperator,
  isMappedTypeNode,
  isMemberName,
  isMetaProperty,
  isMethodDeclaration,
  isMethodOrAccessor,
  isMethodSignature,
  isMinusToken,
  isMissingDeclaration,
  isMissingPackageJsonInfo,
  isModifier,
  isModifierKind,
  isModifierLike,
  isModuleAugmentationExternal,
  isModuleBlock,
  isModuleBody,
  isModuleDeclaration,
  isModuleExportName,
  isModuleExportsAccessExpression,
  isModuleIdentifier,
  isModuleName,
  isModuleOrEnumDeclaration,
  isModuleReference,
  isModuleSpecifierLike,
  isModuleWithStringLiteralName,
  isNameOfFunctionDeclaration,
  isNameOfModuleDeclaration,
  isNamedDeclaration,
  isNamedEvaluation,
  isNamedEvaluationSource,
  isNamedExportBindings,
  isNamedExports,
  isNamedImportBindings,
  isNamedImports,
  isNamedImportsOrExports,
  isNamedTupleMember,
  isNamespaceBody,
  isNamespaceExport,
  isNamespaceExportDeclaration,
  isNamespaceImport,
  isNamespaceReexportDeclaration,
  isNewExpression,
  isNewExpressionTarget,
  isNoSubstitutionTemplateLiteral,
  isNodeArray,
  isNodeArrayMultiLine,
  isNodeDescendantOf,
  isNodeKind,
  isNodeLikeSystem,
  isNodeModulesDirectory,
  isNodeWithPossibleHoistedDeclaration,
  isNonContextualKeyword,
  isNonGlobalAmbientModule,
  isNonNullAccess,
  isNonNullChain,
  isNonNullExpression,
  isNonStaticMethodOrAccessorWithPrivateName,
  isNotEmittedStatement,
  isNullishCoalesce,
  isNumber,
  isNumericLiteral,
  isNumericLiteralName,
  isObjectBindingElementWithoutPropertyName,
  isObjectBindingOrAssignmentElement,
  isObjectBindingOrAssignmentPattern,
  isObjectBindingPattern,
  isObjectLiteralElement,
  isObjectLiteralElementLike,
  isObjectLiteralExpression,
  isObjectLiteralMethod,
  isObjectLiteralOrClassExpressionMethodOrAccessor,
  isObjectTypeDeclaration,
  isOmittedExpression,
  isOptionalChain,
  isOptionalChainRoot,
  isOptionalDeclaration,
  isOptionalJSDocPropertyLikeTag,
  isOptionalTypeNode,
  isOuterExpression,
  isOutermostOptionalChain,
  isOverrideModifier,
  isPackageJsonInfo,
  isPackedArrayLiteral,
  isParameter,
  isParameterPropertyDeclaration,
  isParameterPropertyModifier,
  isParenthesizedExpression,
  isParenthesizedTypeNode,
  isParseTreeNode,
  isPartOfParameterDeclaration,
  isPartOfTypeNode,
  isPartOfTypeQuery,
  isPartiallyEmittedExpression,
  isPatternMatch,
  isPinnedComment,
  isPlainJsFile,
  isPlusToken,
  isPossiblyTypeArgumentPosition,
  isPostfixUnaryExpression,
  isPrefixUnaryExpression,
  isPrimitiveLiteralValue,
  isPrivateIdentifier,
  isPrivateIdentifierClassElementDeclaration,
  isPrivateIdentifierPropertyAccessExpression,
  isPrivateIdentifierSymbol,
  isProgramUptoDate,
  isPrologueDirective,
  isPropertyAccessChain,
  isPropertyAccessEntityNameExpression,
  isPropertyAccessExpression,
  isPropertyAccessOrQualifiedName,
  isPropertyAccessOrQualifiedNameOrImportTypeNode,
  isPropertyAssignment,
  isPropertyDeclaration,
  isPropertyName,
  isPropertyNameLiteral,
  isPropertySignature,
  isPrototypeAccess,
  isPrototypePropertyAssignment,
  isPunctuation,
  isPushOrUnshiftIdentifier,
  isQualifiedName,
  isQuestionDotToken,
  isQuestionOrExclamationToken,
  isQuestionOrPlusOrMinusToken,
  isQuestionToken,
  isReadonlyKeyword,
  isReadonlyKeywordOrPlusOrMinusToken,
  isRecognizedTripleSlashComment,
  isReferenceFileLocation,
  isReferencedFile,
  isRegularExpressionLiteral,
  isRequireCall,
  isRequireVariableStatement,
  isRestParameter,
  isRestTypeNode,
  isReturnStatement,
  isReturnStatementWithFixablePromiseHandler,
  isRightSideOfAccessExpression,
  isRightSideOfInstanceofExpression,
  isRightSideOfPropertyAccess,
  isRightSideOfQualifiedName,
  isRightSideOfQualifiedNameOrPropertyAccess,
  isRightSideOfQualifiedNameOrPropertyAccessOrJSDocMemberName,
  isRootedDiskPath,
  isSameEntityName,
  isSatisfiesExpression,
  isSemicolonClassElement,
  isSetAccessor,
  isSetAccessorDeclaration,
  isShiftOperatorOrHigher,
  isShorthandAmbientModuleSymbol,
  isShorthandPropertyAssignment,
  isSideEffectImport,
  isSignedNumericLiteral,
  isSimpleCopiableExpression,
  isSimpleInlineableExpression,
  isSimpleParameterList,
  isSingleOrDoubleQuote,
  isSourceElement,
  isSourceFile,
  isSourceFileFromLibrary,
  isSourceFileJS,
  isSourceFileNotJson,
  isSourceMapping,
  isSpecialPropertyDeclaration,
  isSpreadAssignment,
  isSpreadElement,
  isStatement,
  isStatementButNotDeclaration,
  isStatementOrBlock,
  isStatementWithLocals,
  isStatic,
  isStaticModifier,
  isString,
  isStringANonContextualKeyword,
  isStringAndEmptyAnonymousObjectIntersection,
  isStringDoubleQuoted,
  isStringLiteral,
  isStringLiteralLike,
  isStringLiteralOrJsxExpression,
  isStringLiteralOrTemplate,
  isStringOrNumericLiteralLike,
  isStringOrRegularExpressionOrTemplateLiteral,
  isStringTextContainingNode,
  isSuperCall,
  isSuperKeyword,
  isSuperProperty,
  isSupportedSourceFileName,
  isSwitchStatement,
  isSyntaxList,
  isSyntheticExpression,
  isSyntheticReference,
  isTagName,
  isTaggedTemplateExpression,
  isTaggedTemplateTag,
  isTemplateExpression,
  isTemplateHead,
  isTemplateLiteral,
  isTemplateLiteralKind,
  isTemplateLiteralToken,
  isTemplateLiteralTypeNode,
  isTemplateLiteralTypeSpan,
  isTemplateMiddle,
  isTemplateMiddleOrTemplateTail,
  isTemplateSpan,
  isTemplateTail,
  isTextWhiteSpaceLike,
  isThis,
  isThisContainerOrFunctionBlock,
  isThisIdentifier,
  isThisInTypeQuery,
  isThisInitializedDeclaration,
  isThisInitializedObjectBindingExpression,
  isThisProperty,
  isThisTypeNode,
  isThisTypeParameter,
  isThisTypePredicate,
  isThrowStatement,
  isToken,
  isTokenKind,
  isTraceEnabled,
  isTransientSymbol,
  isTrivia,
  isTryStatement,
  isTupleTypeNode,
  isTypeAlias,
  isTypeAliasDeclaration,
  isTypeAssertionExpression,
  isTypeDeclaration,
  isTypeElement,
  isTypeKeyword,
  isTypeKeywordTokenOrIdentifier,
  isTypeLiteralNode,
  isTypeNode,
  isTypeNodeKind,
  isTypeOfExpression,
  isTypeOnlyExportDeclaration,
  isTypeOnlyImportDeclaration,
  isTypeOnlyImportOrExportDeclaration,
  isTypeOperatorNode,
  isTypeParameterDeclaration,
  isTypePredicateNode,
  isTypeQueryNode,
  isTypeReferenceNode,
  isTypeReferenceType,
  isTypeUsableAsPropertyName,
  isUMDExportSymbol,
  isUnaryExpression,
  isUnaryExpressionWithWrite,
  isUnicodeIdentifierStart,
  isUnionTypeNode,
  isUrl,
  isValidBigIntString,
  isValidESSymbolDeclaration,
  isValidTypeOnlyAliasUseSite,
  isValueSignatureDeclaration,
  isVarAwaitUsing,
  isVarConst,
  isVarConstLike,
  isVarUsing,
  isVariableDeclaration,
  isVariableDeclarationInVariableStatement,
  isVariableDeclarationInitializedToBareOrAccessedRequire,
  isVariableDeclarationInitializedToRequire,
  isVariableDeclarationList,
  isVariableLike,
  isVariableLikeOrAccessor,
  isVariableStatement,
  isVoidExpression,
  isWatchSet,
  isWhileStatement,
  isWhiteSpaceLike,
  isWhiteSpaceSingleLine,
  isWithStatement,
  isWriteAccess,
  isWriteOnlyAccess,
  isYieldExpression,
  jsxModeNeedsExplicitImport,
  keywordPart,
  last,
  lastOrUndefined,
  length,
  libMap,
  libs,
  lineBreakPart,
  loadModuleFromGlobalCache,
  loadWithModeAwareCache,
  makeIdentifierFromModuleName,
  makeImport,
  makeStringLiteral,
  mangleScopedPackageName,
  map,
  mapAllOrFail,
  mapDefined,
  mapDefinedIterator,
  mapEntries,
  mapIterator,
  mapOneOrMany,
  mapToDisplayParts,
  matchFiles,
  matchPatternOrExact,
  matchedText,
  matchesExclude,
  maxBy,
  maybeBind,
  maybeSetLocalizedDiagnosticMessages,
  memoize,
  memoizeOne,
  min,
  minAndMax,
  missingFileModifiedTime,
  modifierToFlag,
  modifiersToFlags,
  moduleExportNameIsDefault,
  moduleExportNameTextEscaped,
  moduleExportNameTextUnescaped,
  moduleOptionDeclaration,
  moduleResolutionIsEqualTo,
  moduleResolutionNameAndModeGetter,
  moduleResolutionOptionDeclarations,
  moduleResolutionSupportsPackageJsonExportsAndImports,
  moduleResolutionUsesNodeModules,
  moduleSpecifierToValidIdentifier,
  moduleSpecifiers,
  moduleSymbolToValidIdentifier,
  moveEmitHelpers,
  moveRangeEnd,
  moveRangePastDecorators,
  moveRangePastModifiers,
  moveRangePos,
  moveSyntheticComments,
  mutateMap,
  mutateMapSkippingNewValues,
  needsParentheses,
  needsScopeMarker,
  newCaseClauseTracker,
  newPrivateEnvironment,
  noEmitNotification,
  noEmitSubstitution,
  noTransformers,
  noTruncationMaximumTruncationLength,
  nodeCanBeDecorated,
  nodeHasName,
  nodeIsDecorated,
  nodeIsMissing,
  nodeIsPresent,
  nodeIsSynthesized,
  nodeModuleNameResolver,
  nodeModulesPathPart,
  nodeNextJsonConfigResolver,
  nodeOrChildIsDecorated,
  nodeOverlapsWithStartEnd,
  nodePosToString,
  nodeSeenTracker,
  nodeStartsNewLexicalEnvironment,
  noop,
  noopFileWatcher,
  normalizePath,
  normalizeSlashes,
  normalizeSpans,
  not,
  notImplemented,
  notImplementedResolver,
  nullNodeConverters,
  nullParenthesizerRules,
  nullTransformationContext,
  objectAllocator,
  operatorPart,
  optionDeclarations,
  optionMapToObject,
  optionsAffectingProgramStructure,
  optionsForBuild,
  optionsForWatch,
  optionsHaveChanges,
  or,
  orderedRemoveItem,
  orderedRemoveItemAt,
  packageIdToPackageName,
  packageIdToString,
  parameterIsThisKeyword,
  parameterNamePart,
  parseBaseNodeFactory,
  parseBigInt,
  parseBuildCommand,
  parseCommandLine,
  parseCommandLineWorker,
  parseConfigFileTextToJson,
  parseConfigFileWithSystem,
  parseConfigHostFromCompilerHostLike,
  parseCustomTypeOption,
  parseIsolatedEntityName,
  parseIsolatedJSDocComment,
  parseJSDocTypeExpressionForTests,
  parseJsonConfigFileContent,
  parseJsonSourceFileConfigFileContent,
  parseJsonText,
  parseListTypeOption,
  parseNodeFactory,
  parseNodeModuleFromPath,
  parsePackageName,
  parsePseudoBigInt,
  parseValidBigInt,
  pasteEdits,
  patchWriteFileEnsuringDirectory,
  pathContainsNodeModules,
  pathIsAbsolute,
  pathIsBareSpecifier,
  pathIsRelative,
  patternText,
  performIncrementalCompilation,
  performance,
  positionBelongsToNode,
  positionIsASICandidate,
  positionIsSynthesized,
  positionsAreOnSameLine,
  preProcessFile,
  probablyUsesSemicolons,
  processCommentPragmas,
  processPragmasIntoFields,
  processTaggedTemplateExpression,
  programContainsEsModules,
  programContainsModules,
  projectReferenceIsEqualTo,
  propertyNamePart,
  pseudoBigIntToString,
  punctuationPart,
  pushIfUnique,
  quote,
  quotePreferenceFromString,
  rangeContainsPosition,
  rangeContainsPositionExclusive,
  rangeContainsRange,
  rangeContainsRangeExclusive,
  rangeContainsStartEnd,
  rangeEndIsOnSameLineAsRangeStart,
  rangeEndPositionsAreOnSameLine,
  rangeEquals,
  rangeIsOnSingleLine,
  rangeOfNode,
  rangeOfTypeParameters,
  rangeOverlapsWithStartEnd,
  rangeStartIsOnSameLineAsRangeEnd,
  rangeStartPositionsAreOnSameLine,
  readBuilderProgram,
  readConfigFile,
  readJson,
  readJsonConfigFile,
  readJsonOrUndefined,
  reduceEachLeadingCommentRange,
  reduceEachTrailingCommentRange,
  reduceLeft,
  reduceLeftIterator,
  reducePathComponents,
  refactor,
  regExpEscape,
  regularExpressionFlagToCharacterCode,
  relativeComplement,
  removeAllComments,
  removeEmitHelper,
  removeExtension,
  removeFileExtension,
  removeIgnoredPath,
  removeMinAndVersionNumbers,
  removePrefix,
  removeSuffix,
  removeTrailingDirectorySeparator,
  repeatString,
  replaceElement,
  replaceFirstStar,
  resolutionExtensionIsTSOrJson,
  resolveConfigFileProjectName,
  resolveJSModule,
  resolveLibrary,
  resolveModuleName,
  resolveModuleNameFromCache,
  resolvePackageNameToPackageJson,
  resolvePath,
  resolveProjectReferencePath,
  resolveTripleslashReference,
  resolveTypeReferenceDirective,
  resolvingEmptyArray,
  returnFalse,
  returnNoopFileWatcher,
  returnTrue,
  returnUndefined,
  returnsPromise,
  sameFlatMap,
  sameMap,
  sameMapping,
  scanTokenAtPosition,
  scanner,
  semanticDiagnosticsOptionDeclarations,
  serializeCompilerOptions,
  server,
  servicesVersion,
  setCommentRange,
  setConfigFileInOptions,
  setConstantValue,
  setEmitFlags,
  setGetSourceFileAsHashVersioned,
  setIdentifierAutoGenerate,
  setIdentifierGeneratedImportReference,
  setIdentifierTypeArguments,
  setInternalEmitFlags,
  setLocalizedDiagnosticMessages,
  setNodeChildren,
  setNodeFlags,
  setObjectAllocator,
  setOriginalNode,
  setParent,
  setParentRecursive,
  setPrivateIdentifier,
  setSnippetElement,
  setSourceMapRange,
  setStackTraceLimit,
  setStartsOnNewLine,
  setSyntheticLeadingComments,
  setSyntheticTrailingComments,
  setSys,
  setSysLog,
  setTextRange,
  setTextRangeEnd,
  setTextRangePos,
  setTextRangePosEnd,
  setTextRangePosWidth,
  setTokenSourceMapRange,
  setTypeNode,
  setUILocale,
  setValueDeclaration,
  shouldAllowImportingTsExtension,
  shouldPreserveConstEnums,
  shouldUseUriStyleNodeCoreModules,
  showModuleSpecifier,
  signatureHasRestParameter,
  signatureToDisplayParts,
  single,
  singleElementArray,
  singleIterator,
  singleOrMany,
  singleOrUndefined,
  skipAlias,
  skipConstraint,
  skipOuterExpressions,
  skipParentheses,
  skipPartiallyEmittedExpressions,
  skipTrivia,
  skipTypeChecking,
  skipTypeCheckingIgnoringNoCheck,
  skipTypeParentheses,
  skipWhile,
  sliceAfter,
  some,
  sortAndDeduplicate,
  sortAndDeduplicateDiagnostics,
  sourceFileAffectingCompilerOptions,
  sourceFileMayBeEmitted,
  sourceMapCommentRegExp,
  sourceMapCommentRegExpDontCareLineStart,
  spacePart,
  spanMap,
  startEndContainsRange,
  startEndOverlapsWithStartEnd,
  startOnNewLine,
  startTracing,
  startsWith,
  startsWithDirectory,
  startsWithUnderscore,
  startsWithUseStrict,
  stringContainsAt,
  stringToToken,
  stripQuotes,
  supportedDeclarationExtensions,
  supportedJSExtensionsFlat,
  supportedLocaleDirectories,
  supportedTSExtensionsFlat,
  supportedTSImplementationExtensions,
  suppressLeadingAndTrailingTrivia,
  suppressLeadingTrivia,
  suppressTrailingTrivia,
  symbolEscapedNameNoDefault,
  symbolName,
  symbolNameNoDefault,
  symbolToDisplayParts,
  sys,
  sysLog,
  tagNamesAreEquivalent,
  takeWhile,
  targetOptionDeclaration,
  testFormatSettings,
  textChangeRangeIsUnchanged,
  textChangeRangeNewSpan,
  textChanges,
  textOrKeywordPart,
  textPart,
  textRangeContainsPositionInclusive,
  textRangeContainsTextSpan,
  textRangeIntersectsWithTextSpan,
  textSpanContainsPosition,
  textSpanContainsTextRange,
  textSpanContainsTextSpan,
  textSpanEnd,
  textSpanIntersection,
  textSpanIntersectsWith,
  textSpanIntersectsWithPosition,
  textSpanIntersectsWithTextSpan,
  textSpanIsEmpty,
  textSpanOverlap,
  textSpanOverlapsWith,
  textSpansEqual,
  textToKeywordObj,
  timestamp,
  toArray,
  toBuilderFileEmit,
  toBuilderStateFileInfoForMultiEmit,
  toEditorSettings,
  toFileNameLowerCase,
  toPath,
  toProgramEmitPending,
  toSorted,
  tokenIsIdentifierOrKeyword,
  tokenIsIdentifierOrKeywordOrGreaterThan,
  tokenToString,
  trace,
  tracing,
  tracingEnabled,
  transferSourceFileChildren,
  transform,
  transformClassFields,
  transformDeclarations,
  transformECMAScriptModule,
  transformES2015,
  transformES2016,
  transformES2017,
  transformES2018,
  transformES2019,
  transformES2020,
  transformES2021,
  transformESDecorators,
  transformESNext,
  transformGenerators,
  transformImpliedNodeFormatDependentModule,
  transformJsx,
  transformLegacyDecorators,
  transformModule,
  transformNamedEvaluation,
  transformNodes,
  transformSystemModule,
  transformTypeScript,
  transpile,
  transpileDeclaration,
  transpileModule,
  transpileOptionValueCompilerOptions,
  tryAddToSet,
  tryAndIgnoreErrors,
  tryCast,
  tryDirectoryExists,
  tryExtractTSExtension,
  tryFileExists,
  tryGetClassExtendingExpressionWithTypeArguments,
  tryGetClassImplementingOrExtendingExpressionWithTypeArguments,
  tryGetDirectories,
  tryGetExtensionFromPath,
  tryGetImportFromModuleSpecifier,
  tryGetJSDocSatisfiesTypeNode,
  tryGetModuleNameFromFile,
  tryGetModuleSpecifierFromDeclaration,
  tryGetNativePerformanceHooks,
  tryGetPropertyAccessOrIdentifierToString,
  tryGetPropertyNameOfBindingOrAssignmentElement,
  tryGetSourceMappingURL,
  tryGetTextOfPropertyName,
  tryParseJson,
  tryParsePattern,
  tryParsePatterns,
  tryParseRawSourceMap,
  tryReadDirectory,
  tryReadFile,
  tryRemoveDirectoryPrefix,
  tryRemoveExtension,
  tryRemovePrefix,
  tryRemoveSuffix,
  typeAcquisitionDeclarations,
  typeAliasNamePart,
  typeDirectiveIsEqualTo,
  typeKeywords,
  typeParameterNamePart,
  typeToDisplayParts,
  unchangedPollThresholds,
  unchangedTextChangeRange,
  unescapeLeadingUnderscores,
  unmangleScopedPackageName,
  unorderedRemoveItem,
  unreachableCodeIsError,
  unsetNodeChildren,
  unusedLabelIsError,
  unwrapInnermostStatementOfLabel,
  unwrapParenthesizedExpression,
  updateErrorForNoInputFiles,
  updateLanguageServiceSourceFile,
  updateMissingFilePathsWatch,
  updateResolutionField,
  updateSharedExtendedConfigFileWatcher,
  updateSourceFile,
  updateWatchingWildcardDirectories,
  usingSingleLineStringWriter,
  utf16EncodeAsString,
  validateLocaleAndSetLanguage,
  version,
  versionMajorMinor,
  visitArray,
  visitCommaListElements,
  visitEachChild,
  visitFunctionBody,
  visitIterationBody,
  visitLexicalEnvironment,
  visitNode,
  visitNodes,
  visitParameterList,
  walkUpBindingElementsAndPatterns,
  walkUpOuterExpressions,
  walkUpParenthesizedExpressions,
  walkUpParenthesizedTypes,
  walkUpParenthesizedTypesAndGetParentAndChild,
  whitespaceOrMapCommentRegExp,
  writeCommentRange,
  writeFile,
  writeFileEnsuringDirectories,
  zipWith
});
})({ get exports() { return ts; }, set exports(v) { ts = v; if (typeof module !== "undefined" && module.exports) { module.exports = v; } } })
//# sourceMappingURL=typescript.js.map
