"use strict";
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
const event = require("../../../base/common/event.js");
const lifecycle = require("../../../base/common/lifecycle.js");
const languagesRegistry = require("./languagesRegistry.js");
const arrays = require("../../../base/common/arrays.js");
const languages = require("../languages.js");
const modesRegistry = require("../languages/modesRegistry.js");
class LanguageService extends lifecycle.Disposable {
  constructor(warnOnOverwrite = false) {
    super();
    this._onDidEncounterLanguage = this._register(new event.Emitter());
    this.onDidEncounterLanguage = this._onDidEncounterLanguage.event;
    this._onDidChange = this._register(new event.Emitter({
      leakWarningThreshold: 200
      /* https://github.com/microsoft/vscode/issues/119968 */
    }));
    this.onDidChange = this._onDidChange.event;
    LanguageService.instanceCount++;
    this._encounteredLanguages = /* @__PURE__ */ new Set();
    this._registry = this._register(new languagesRegistry.LanguagesRegistry(true, warnOnOverwrite));
    this.languageIdCodec = this._registry.languageIdCodec;
    this._register(this._registry.onDidChange(() => this._onDidChange.fire()));
  }
  dispose() {
    LanguageService.instanceCount--;
    super.dispose();
  }
  isRegisteredLanguageId(languageId) {
    return this._registry.isRegisteredLanguageId(languageId);
  }
  getLanguageIdByLanguageName(languageName) {
    return this._registry.getLanguageIdByLanguageName(languageName);
  }
  getLanguageIdByMimeType(mimeType) {
    return this._registry.getLanguageIdByMimeType(mimeType);
  }
  guessLanguageIdByFilepathOrFirstLine(resource, firstLine) {
    const languageIds = this._registry.guessLanguageIdByFilepathOrFirstLine(resource, firstLine);
    return arrays.firstOrDefault(languageIds, null);
  }
  createById(languageId) {
    return new LanguageSelection(this.onDidChange, () => {
      return this._createAndGetLanguageIdentifier(languageId);
    });
  }
  createByFilepathOrFirstLine(resource, firstLine) {
    return new LanguageSelection(this.onDidChange, () => {
      const languageId = this.guessLanguageIdByFilepathOrFirstLine(resource, firstLine);
      return this._createAndGetLanguageIdentifier(languageId);
    });
  }
  _createAndGetLanguageIdentifier(languageId) {
    if (!languageId || !this.isRegisteredLanguageId(languageId)) {
      languageId = modesRegistry.PLAINTEXT_LANGUAGE_ID;
    }
    if (!this._encounteredLanguages.has(languageId)) {
      this._encounteredLanguages.add(languageId);
      languages.TokenizationRegistry.getOrCreate(languageId);
      this._onDidEncounterLanguage.fire(languageId);
    }
    return languageId;
  }
}
LanguageService.instanceCount = 0;
class LanguageSelection {
  constructor(_onDidChangeLanguages, _selector) {
    this._onDidChangeLanguages = _onDidChangeLanguages;
    this._selector = _selector;
    this._listener = null;
    this._emitter = null;
    this.languageId = this._selector();
  }
  _dispose() {
    if (this._listener) {
      this._listener.dispose();
      this._listener = null;
    }
    if (this._emitter) {
      this._emitter.dispose();
      this._emitter = null;
    }
  }
  get onDidChange() {
    if (!this._listener) {
      this._listener = this._onDidChangeLanguages(() => this._evaluate());
    }
    if (!this._emitter) {
      this._emitter = new event.Emitter({
        onLastListenerRemove: () => {
          this._dispose();
        }
      });
    }
    return this._emitter.event;
  }
  _evaluate() {
    const languageId = this._selector();
    if (languageId === this.languageId) {
      return;
    }
    this.languageId = languageId;
    if (this._emitter) {
      this._emitter.fire(this.languageId);
    }
  }
}
exports.LanguageService = LanguageService;
