"use strict";
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
const async = require("../../../../base/common/async.js");
const codicons = require("../../../../base/common/codicons.js");
const lifecycle = require("../../../../base/common/lifecycle.js");
const platform = require("../../../../base/common/platform.js");
const strings = require("../../../../base/common/strings.js");
require("./unicodeHighlighter.css.js");
const editorExtensions = require("../../../browser/editorExtensions.js");
const editorOptions = require("../../../common/config/editorOptions.js");
const textModel = require("../../../common/model/textModel.js");
const unicodeTextModelHighlighter = require("../../../common/services/unicodeTextModelHighlighter.js");
const editorWorker = require("../../../common/services/editorWorker.js");
const language = require("../../../common/languages/language.js");
const viewModelDecorations = require("../../../common/viewModel/viewModelDecorations.js");
const hoverTypes = require("../../hover/browser/hoverTypes.js");
const markdownHoverParticipant = require("../../hover/browser/markdownHoverParticipant.js");
const bannerController = require("./bannerController.js");
const nls = require("../../../../nls.js");
const configuration = require("../../../../platform/configuration/common/configuration.js");
const instantiation = require("../../../../platform/instantiation/common/instantiation.js");
const opener = require("../../../../platform/opener/common/opener.js");
const quickInput = require("../../../../platform/quickinput/common/quickInput.js");
const iconRegistry = require("../../../../platform/theme/common/iconRegistry.js");
const workspaceTrust = require("../../../../platform/workspace/common/workspaceTrust.js");
var __decorate = globalThis && globalThis.__decorate || function(decorators, target, key, desc) {
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function")
    r = Reflect.decorate(decorators, target, key, desc);
  else
    for (var i = decorators.length - 1; i >= 0; i--)
      if (d = decorators[i])
        r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
  return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __param = globalThis && globalThis.__param || function(paramIndex, decorator) {
  return function(target, key) {
    decorator(target, key, paramIndex);
  };
};
var __awaiter = globalThis && globalThis.__awaiter || function(thisArg, _arguments, P, generator) {
  function adopt(value) {
    return value instanceof P ? value : new P(function(resolve) {
      resolve(value);
    });
  }
  return new (P || (P = Promise))(function(resolve, reject) {
    function fulfilled(value) {
      try {
        step(generator.next(value));
      } catch (e) {
        reject(e);
      }
    }
    function rejected(value) {
      try {
        step(generator["throw"](value));
      } catch (e) {
        reject(e);
      }
    }
    function step(result) {
      result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected);
    }
    step((generator = generator.apply(thisArg, _arguments || [])).next());
  });
};
const warningIcon = iconRegistry.registerIcon("extensions-warning-message", codicons.Codicon.warning, nls.localize("warningIcon", "Icon shown with a warning message in the extensions editor."));
exports.UnicodeHighlighter = class UnicodeHighlighter extends lifecycle.Disposable {
  constructor(_editor, _editorWorkerService, _workspaceTrustService, instantiationService) {
    super();
    this._editor = _editor;
    this._editorWorkerService = _editorWorkerService;
    this._workspaceTrustService = _workspaceTrustService;
    this._highlighter = null;
    this._bannerClosed = false;
    this._updateState = (state) => {
      if (state && state.hasMore) {
        if (this._bannerClosed) {
          return;
        }
        const max = Math.max(state.ambiguousCharacterCount, state.nonBasicAsciiCharacterCount, state.invisibleCharacterCount);
        let data;
        if (state.nonBasicAsciiCharacterCount >= max) {
          data = {
            message: nls.localize("unicodeHighlighting.thisDocumentHasManyNonBasicAsciiUnicodeCharacters", "This document contains many non-basic ASCII unicode characters"),
            command: new DisableHighlightingOfNonBasicAsciiCharactersAction()
          };
        } else if (state.ambiguousCharacterCount >= max) {
          data = {
            message: nls.localize("unicodeHighlighting.thisDocumentHasManyAmbiguousUnicodeCharacters", "This document contains many ambiguous unicode characters"),
            command: new DisableHighlightingOfAmbiguousCharactersAction()
          };
        } else if (state.invisibleCharacterCount >= max) {
          data = {
            message: nls.localize("unicodeHighlighting.thisDocumentHasManyInvisibleUnicodeCharacters", "This document contains many invisible unicode characters"),
            command: new DisableHighlightingOfInvisibleCharactersAction()
          };
        } else {
          throw new Error("Unreachable");
        }
        this._bannerController.show({
          id: "unicodeHighlightBanner",
          message: data.message,
          icon: warningIcon,
          actions: [
            {
              label: data.command.shortLabel,
              href: `command:${data.command.id}`
            }
          ],
          onClose: () => {
            this._bannerClosed = true;
          }
        });
      } else {
        this._bannerController.hide();
      }
    };
    this._bannerController = this._register(instantiationService.createInstance(bannerController.BannerController, _editor));
    this._register(this._editor.onDidChangeModel(() => {
      this._bannerClosed = false;
      this._updateHighlighter();
    }));
    this._options = _editor.getOption(
      113
      /* unicodeHighlighting */
    );
    this._register(_workspaceTrustService.onDidChangeTrust((e) => {
      this._updateHighlighter();
    }));
    this._register(_editor.onDidChangeConfiguration((e) => {
      if (e.hasChanged(
        113
        /* unicodeHighlighting */
      )) {
        this._options = _editor.getOption(
          113
          /* unicodeHighlighting */
        );
        this._updateHighlighter();
      }
    }));
    this._updateHighlighter();
  }
  dispose() {
    if (this._highlighter) {
      this._highlighter.dispose();
      this._highlighter = null;
    }
    super.dispose();
  }
  _updateHighlighter() {
    this._updateState(null);
    if (this._highlighter) {
      this._highlighter.dispose();
      this._highlighter = null;
    }
    if (!this._editor.hasModel()) {
      return;
    }
    const options = resolveOptions(this._workspaceTrustService.isWorkspaceTrusted(), this._options);
    if ([
      options.nonBasicASCII,
      options.ambiguousCharacters,
      options.invisibleCharacters
    ].every((option) => option === false)) {
      return;
    }
    const highlightOptions = {
      nonBasicASCII: options.nonBasicASCII,
      ambiguousCharacters: options.ambiguousCharacters,
      invisibleCharacters: options.invisibleCharacters,
      includeComments: options.includeComments,
      includeStrings: options.includeStrings,
      allowedCodePoints: Object.keys(options.allowedCharacters).map((c) => c.codePointAt(0)),
      allowedLocales: Object.keys(options.allowedLocales).map((locale) => {
        if (locale === "_os") {
          let osLocale = new Intl.NumberFormat().resolvedOptions().locale;
          return osLocale;
        } else if (locale === "_vscode") {
          return platform.language;
        }
        return locale;
      })
    };
    if (this._editorWorkerService.canComputeUnicodeHighlights(this._editor.getModel().uri)) {
      this._highlighter = new DocumentUnicodeHighlighter(this._editor, highlightOptions, this._updateState, this._editorWorkerService);
    } else {
      this._highlighter = new ViewportUnicodeHighlighter(this._editor, highlightOptions, this._updateState);
    }
  }
  getDecorationInfo(decorationId) {
    if (this._highlighter) {
      return this._highlighter.getDecorationInfo(decorationId);
    }
    return null;
  }
};
exports.UnicodeHighlighter.ID = "editor.contrib.unicodeHighlighter";
exports.UnicodeHighlighter = __decorate([
  __param(1, editorWorker.IEditorWorkerService),
  __param(2, workspaceTrust.IWorkspaceTrustManagementService),
  __param(3, instantiation.IInstantiationService)
], exports.UnicodeHighlighter);
function resolveOptions(trusted, options) {
  return {
    nonBasicASCII: options.nonBasicASCII === editorOptions.inUntrustedWorkspace ? !trusted : options.nonBasicASCII,
    ambiguousCharacters: options.ambiguousCharacters,
    invisibleCharacters: options.invisibleCharacters,
    includeComments: options.includeComments === editorOptions.inUntrustedWorkspace ? !trusted : options.includeComments,
    includeStrings: options.includeStrings === editorOptions.inUntrustedWorkspace ? !trusted : options.includeStrings,
    allowedCharacters: options.allowedCharacters,
    allowedLocales: options.allowedLocales
  };
}
let DocumentUnicodeHighlighter = class DocumentUnicodeHighlighter2 extends lifecycle.Disposable {
  constructor(_editor, _options, _updateState, _editorWorkerService) {
    super();
    this._editor = _editor;
    this._options = _options;
    this._updateState = _updateState;
    this._editorWorkerService = _editorWorkerService;
    this._model = this._editor.getModel();
    this._decorationIds = /* @__PURE__ */ new Set();
    this._updateSoon = this._register(new async.RunOnceScheduler(() => this._update(), 250));
    this._register(this._editor.onDidChangeModelContent(() => {
      this._updateSoon.schedule();
    }));
    this._updateSoon.schedule();
  }
  dispose() {
    this._decorationIds = new Set(this._model.deltaDecorations(Array.from(this._decorationIds), []));
    super.dispose();
  }
  _update() {
    if (this._model.isDisposed()) {
      return;
    }
    if (!this._model.mightContainNonBasicASCII()) {
      this._decorationIds = new Set(this._editor.deltaDecorations(Array.from(this._decorationIds), []));
      return;
    }
    const modelVersionId = this._model.getVersionId();
    this._editorWorkerService.computedUnicodeHighlights(this._model.uri, this._options).then((info) => {
      if (this._model.isDisposed()) {
        return;
      }
      if (this._model.getVersionId() !== modelVersionId) {
        return;
      }
      this._updateState(info);
      const decorations = [];
      if (!info.hasMore) {
        for (const range of info.ranges) {
          decorations.push({
            range,
            options: Decorations.instance.getDecorationFromOptions(this._options)
          });
        }
      }
      this._decorationIds = new Set(this._editor.deltaDecorations(Array.from(this._decorationIds), decorations));
    });
  }
  getDecorationInfo(decorationId) {
    if (!this._decorationIds.has(decorationId)) {
      return null;
    }
    const model = this._editor.getModel();
    const range = model.getDecorationRange(decorationId);
    const decoration = {
      range,
      options: Decorations.instance.getDecorationFromOptions(this._options),
      id: decorationId,
      ownerId: 0
    };
    if (!viewModelDecorations.isModelDecorationVisible(model, decoration)) {
      return null;
    }
    const text = model.getValueInRange(range);
    return {
      reason: computeReason(text, this._options),
      inComment: viewModelDecorations.isModelDecorationInComment(model, decoration),
      inString: viewModelDecorations.isModelDecorationInString(model, decoration)
    };
  }
};
DocumentUnicodeHighlighter = __decorate([
  __param(3, editorWorker.IEditorWorkerService)
], DocumentUnicodeHighlighter);
class ViewportUnicodeHighlighter extends lifecycle.Disposable {
  constructor(_editor, _options, _updateState) {
    super();
    this._editor = _editor;
    this._options = _options;
    this._updateState = _updateState;
    this._model = this._editor.getModel();
    this._decorationIds = /* @__PURE__ */ new Set();
    this._updateSoon = this._register(new async.RunOnceScheduler(() => this._update(), 250));
    this._register(this._editor.onDidLayoutChange(() => {
      this._updateSoon.schedule();
    }));
    this._register(this._editor.onDidScrollChange(() => {
      this._updateSoon.schedule();
    }));
    this._register(this._editor.onDidChangeHiddenAreas(() => {
      this._updateSoon.schedule();
    }));
    this._register(this._editor.onDidChangeModelContent(() => {
      this._updateSoon.schedule();
    }));
    this._updateSoon.schedule();
  }
  dispose() {
    this._decorationIds = new Set(this._model.deltaDecorations(Array.from(this._decorationIds), []));
    super.dispose();
  }
  _update() {
    if (this._model.isDisposed()) {
      return;
    }
    if (!this._model.mightContainNonBasicASCII()) {
      this._decorationIds = new Set(this._editor.deltaDecorations(Array.from(this._decorationIds), []));
      return;
    }
    const ranges = this._editor.getVisibleRanges();
    const decorations = [];
    const totalResult = {
      ranges: [],
      ambiguousCharacterCount: 0,
      invisibleCharacterCount: 0,
      nonBasicAsciiCharacterCount: 0,
      hasMore: false
    };
    for (const range of ranges) {
      const result = unicodeTextModelHighlighter.UnicodeTextModelHighlighter.computeUnicodeHighlights(this._model, this._options, range);
      for (const r of result.ranges) {
        totalResult.ranges.push(r);
      }
      totalResult.ambiguousCharacterCount += totalResult.ambiguousCharacterCount;
      totalResult.invisibleCharacterCount += totalResult.invisibleCharacterCount;
      totalResult.nonBasicAsciiCharacterCount += totalResult.nonBasicAsciiCharacterCount;
      totalResult.hasMore = totalResult.hasMore || result.hasMore;
    }
    if (!totalResult.hasMore) {
      for (const range of totalResult.ranges) {
        decorations.push({ range, options: Decorations.instance.getDecorationFromOptions(this._options) });
      }
    }
    this._updateState(totalResult);
    this._decorationIds = new Set(this._editor.deltaDecorations(Array.from(this._decorationIds), decorations));
  }
  getDecorationInfo(decorationId) {
    if (!this._decorationIds.has(decorationId)) {
      return null;
    }
    const model = this._editor.getModel();
    const range = model.getDecorationRange(decorationId);
    const text = model.getValueInRange(range);
    const decoration = {
      range,
      options: Decorations.instance.getDecorationFromOptions(this._options),
      id: decorationId,
      ownerId: 0
    };
    if (!viewModelDecorations.isModelDecorationVisible(model, decoration)) {
      return null;
    }
    return {
      reason: computeReason(text, this._options),
      inComment: viewModelDecorations.isModelDecorationInComment(model, decoration),
      inString: viewModelDecorations.isModelDecorationInString(model, decoration)
    };
  }
}
exports.UnicodeHighlighterHoverParticipant = class UnicodeHighlighterHoverParticipant {
  constructor(_editor, _languageService, _openerService) {
    this._editor = _editor;
    this._languageService = _languageService;
    this._openerService = _openerService;
    this.hoverOrdinal = 4;
  }
  computeSync(anchor, lineDecorations) {
    if (!this._editor.hasModel() || anchor.type !== 1) {
      return [];
    }
    const model = this._editor.getModel();
    const unicodeHighlighter = this._editor.getContribution(exports.UnicodeHighlighter.ID);
    if (!unicodeHighlighter) {
      return [];
    }
    const result = [];
    let index = 300;
    for (const d of lineDecorations) {
      const highlightInfo = unicodeHighlighter.getDecorationInfo(d.id);
      if (!highlightInfo) {
        continue;
      }
      const char = model.getValueInRange(d.range);
      const codePoint = char.codePointAt(0);
      const codePointStr = formatCodePointMarkdown(codePoint);
      let reason;
      switch (highlightInfo.reason.kind) {
        case 0:
          reason = nls.localize("unicodeHighlight.characterIsAmbiguous", "The character {0} could be confused with the character {1}, which is more common in source code.", codePointStr, formatCodePointMarkdown(highlightInfo.reason.confusableWith.codePointAt(0)));
          break;
        case 1:
          reason = nls.localize("unicodeHighlight.characterIsInvisible", "The character {0} is invisible.", codePointStr);
          break;
        case 2:
          reason = nls.localize("unicodeHighlight.characterIsNonBasicAscii", "The character {0} is not a basic ASCII character.", codePointStr);
          break;
      }
      const adjustSettingsArgs = {
        codePoint,
        reason: highlightInfo.reason,
        inComment: highlightInfo.inComment,
        inString: highlightInfo.inString
      };
      const adjustSettings = nls.localize("unicodeHighlight.adjustSettings", "Adjust settings");
      const contents = [{
        value: `${reason} [${adjustSettings}](command:${ShowExcludeOptions.ID}?${encodeURIComponent(JSON.stringify(adjustSettingsArgs))})`,
        isTrusted: true
      }];
      result.push(new markdownHoverParticipant.MarkdownHover(this, d.range, contents, index++));
    }
    return result;
  }
  renderHoverParts(context, hoverParts) {
    return markdownHoverParticipant.renderMarkdownHovers(context, hoverParts, this._editor, this._languageService, this._openerService);
  }
};
exports.UnicodeHighlighterHoverParticipant = __decorate([
  __param(1, language.ILanguageService),
  __param(2, opener.IOpenerService)
], exports.UnicodeHighlighterHoverParticipant);
function codePointToHex(codePoint) {
  return `U+${codePoint.toString(16).padStart(4, "0")}`;
}
function formatCodePointMarkdown(codePoint) {
  let value = `\`${codePointToHex(codePoint)}\``;
  if (!strings.InvisibleCharacters.isInvisibleCharacter(codePoint)) {
    value += ` "${`${renderCodePointAsInlineCode(codePoint)}`}"`;
  }
  return value;
}
function renderCodePointAsInlineCode(codePoint) {
  if (codePoint === 96) {
    return "`` ` ``";
  }
  return "`" + String.fromCodePoint(codePoint) + "`";
}
function computeReason(char, options) {
  return unicodeTextModelHighlighter.UnicodeTextModelHighlighter.computeUnicodeHighlightReason(char, options);
}
class Decorations {
  constructor() {
    this.map = /* @__PURE__ */ new Map();
  }
  getDecorationFromOptions(options) {
    return this.getDecoration(!options.includeComments, !options.includeStrings);
  }
  getDecoration(hideInComments, hideInStrings) {
    const key = `${hideInComments}${hideInStrings}`;
    let options = this.map.get(key);
    if (!options) {
      options = textModel.ModelDecorationOptions.createDynamic({
        description: "unicode-highlight",
        stickiness: 1,
        className: "unicode-highlight",
        showIfCollapsed: true,
        overviewRuler: null,
        minimap: null,
        hideInCommentTokens: hideInComments,
        hideInStringTokens: hideInStrings
      });
      this.map.set(key, options);
    }
    return options;
  }
}
Decorations.instance = new Decorations();
class DisableHighlightingInCommentsAction extends editorExtensions.EditorAction {
  constructor() {
    super({
      id: DisableHighlightingOfAmbiguousCharactersAction.ID,
      label: nls.localize("action.unicodeHighlight.disableHighlightingInComments", "Disable highlighting of characters in comments"),
      alias: "Disable highlighting of characters in comments",
      precondition: void 0
    });
    this.shortLabel = nls.localize("unicodeHighlight.disableHighlightingInComments.shortLabel", "Disable Highlight In Comments");
  }
  run(accessor, editor, args) {
    return __awaiter(this, void 0, void 0, function* () {
      let configurationService = accessor === null || accessor === void 0 ? void 0 : accessor.get(configuration.IConfigurationService);
      if (configurationService) {
        this.runAction(configurationService);
      }
    });
  }
  runAction(configurationService) {
    return __awaiter(this, void 0, void 0, function* () {
      yield configurationService.updateValue(
        editorOptions.unicodeHighlightConfigKeys.includeComments,
        false,
        1
        /* USER */
      );
    });
  }
}
class DisableHighlightingInStringsAction extends editorExtensions.EditorAction {
  constructor() {
    super({
      id: DisableHighlightingOfAmbiguousCharactersAction.ID,
      label: nls.localize("action.unicodeHighlight.disableHighlightingInStrings", "Disable highlighting of characters in strings"),
      alias: "Disable highlighting of characters in strings",
      precondition: void 0
    });
    this.shortLabel = nls.localize("unicodeHighlight.disableHighlightingInStrings.shortLabel", "Disable Highlight In Strings");
  }
  run(accessor, editor, args) {
    return __awaiter(this, void 0, void 0, function* () {
      let configurationService = accessor === null || accessor === void 0 ? void 0 : accessor.get(configuration.IConfigurationService);
      if (configurationService) {
        this.runAction(configurationService);
      }
    });
  }
  runAction(configurationService) {
    return __awaiter(this, void 0, void 0, function* () {
      yield configurationService.updateValue(
        editorOptions.unicodeHighlightConfigKeys.includeStrings,
        false,
        1
        /* USER */
      );
    });
  }
}
class DisableHighlightingOfAmbiguousCharactersAction extends editorExtensions.EditorAction {
  constructor() {
    super({
      id: DisableHighlightingOfAmbiguousCharactersAction.ID,
      label: nls.localize("action.unicodeHighlight.disableHighlightingOfAmbiguousCharacters", "Disable highlighting of ambiguous characters"),
      alias: "Disable highlighting of ambiguous characters",
      precondition: void 0
    });
    this.shortLabel = nls.localize("unicodeHighlight.disableHighlightingOfAmbiguousCharacters.shortLabel", "Disable Ambiguous Highlight");
  }
  run(accessor, editor, args) {
    return __awaiter(this, void 0, void 0, function* () {
      let configurationService = accessor === null || accessor === void 0 ? void 0 : accessor.get(configuration.IConfigurationService);
      if (configurationService) {
        this.runAction(configurationService);
      }
    });
  }
  runAction(configurationService) {
    return __awaiter(this, void 0, void 0, function* () {
      yield configurationService.updateValue(
        editorOptions.unicodeHighlightConfigKeys.ambiguousCharacters,
        false,
        1
        /* USER */
      );
    });
  }
}
DisableHighlightingOfAmbiguousCharactersAction.ID = "editor.action.unicodeHighlight.disableHighlightingOfAmbiguousCharacters";
class DisableHighlightingOfInvisibleCharactersAction extends editorExtensions.EditorAction {
  constructor() {
    super({
      id: DisableHighlightingOfInvisibleCharactersAction.ID,
      label: nls.localize("action.unicodeHighlight.disableHighlightingOfInvisibleCharacters", "Disable highlighting of invisible characters"),
      alias: "Disable highlighting of invisible characters",
      precondition: void 0
    });
    this.shortLabel = nls.localize("unicodeHighlight.disableHighlightingOfInvisibleCharacters.shortLabel", "Disable Invisible Highlight");
  }
  run(accessor, editor, args) {
    return __awaiter(this, void 0, void 0, function* () {
      let configurationService = accessor === null || accessor === void 0 ? void 0 : accessor.get(configuration.IConfigurationService);
      if (configurationService) {
        this.runAction(configurationService);
      }
    });
  }
  runAction(configurationService) {
    return __awaiter(this, void 0, void 0, function* () {
      yield configurationService.updateValue(
        editorOptions.unicodeHighlightConfigKeys.invisibleCharacters,
        false,
        1
        /* USER */
      );
    });
  }
}
DisableHighlightingOfInvisibleCharactersAction.ID = "editor.action.unicodeHighlight.disableHighlightingOfInvisibleCharacters";
class DisableHighlightingOfNonBasicAsciiCharactersAction extends editorExtensions.EditorAction {
  constructor() {
    super({
      id: DisableHighlightingOfNonBasicAsciiCharactersAction.ID,
      label: nls.localize("action.unicodeHighlight.disableHighlightingOfNonBasicAsciiCharacters", "Disable highlighting of non basic ASCII characters"),
      alias: "Disable highlighting of non basic ASCII characters",
      precondition: void 0
    });
    this.shortLabel = nls.localize("unicodeHighlight.disableHighlightingOfNonBasicAsciiCharacters.shortLabel", "Disable Non ASCII Highlight");
  }
  run(accessor, editor, args) {
    return __awaiter(this, void 0, void 0, function* () {
      let configurationService = accessor === null || accessor === void 0 ? void 0 : accessor.get(configuration.IConfigurationService);
      if (configurationService) {
        this.runAction(configurationService);
      }
    });
  }
  runAction(configurationService) {
    return __awaiter(this, void 0, void 0, function* () {
      yield configurationService.updateValue(
        editorOptions.unicodeHighlightConfigKeys.nonBasicASCII,
        false,
        1
        /* USER */
      );
    });
  }
}
DisableHighlightingOfNonBasicAsciiCharactersAction.ID = "editor.action.unicodeHighlight.disableHighlightingOfNonBasicAsciiCharacters";
class ShowExcludeOptions extends editorExtensions.EditorAction {
  constructor() {
    super({
      id: ShowExcludeOptions.ID,
      label: nls.localize("action.unicodeHighlight.showExcludeOptions", "Show Exclude Options"),
      alias: "Show Exclude Options",
      precondition: void 0
    });
  }
  run(accessor, editor, args) {
    return __awaiter(this, void 0, void 0, function* () {
      const { codePoint, reason, inString, inComment } = args;
      const char = String.fromCodePoint(codePoint);
      const quickPickService = accessor.get(quickInput.IQuickInputService);
      const configurationService = accessor.get(configuration.IConfigurationService);
      function getExcludeCharFromBeingHighlightedLabel(codePoint2) {
        if (strings.InvisibleCharacters.isInvisibleCharacter(codePoint2)) {
          return nls.localize("unicodeHighlight.excludeInvisibleCharFromBeingHighlighted", "Exclude {0} (invisible character) from being highlighted", codePointToHex(codePoint2));
        }
        return nls.localize("unicodeHighlight.excludeCharFromBeingHighlighted", "Exclude {0} from being highlighted", `${codePointToHex(codePoint2)} "${char}"`);
      }
      const options = [];
      if (reason.kind === 0) {
        for (const locale of reason.notAmbiguousInLocales) {
          options.push({
            label: nls.localize("unicodeHighlight.allowCommonCharactersInLanguage", 'Allow unicode characters that are more common in the language "{0}".', locale),
            run: () => __awaiter(this, void 0, void 0, function* () {
              excludeLocaleFromBeingHighlighted(configurationService, [locale]);
            })
          });
        }
      }
      options.push({
        label: getExcludeCharFromBeingHighlightedLabel(codePoint),
        run: () => excludeCharFromBeingHighlighted(configurationService, [codePoint])
      });
      if (inComment) {
        const action = new DisableHighlightingInCommentsAction();
        options.push({ label: action.label, run: () => __awaiter(this, void 0, void 0, function* () {
          return action.runAction(configurationService);
        }) });
      } else if (inString) {
        const action = new DisableHighlightingInStringsAction();
        options.push({ label: action.label, run: () => __awaiter(this, void 0, void 0, function* () {
          return action.runAction(configurationService);
        }) });
      }
      if (reason.kind === 0) {
        const action = new DisableHighlightingOfAmbiguousCharactersAction();
        options.push({ label: action.label, run: () => __awaiter(this, void 0, void 0, function* () {
          return action.runAction(configurationService);
        }) });
      } else if (reason.kind === 1) {
        const action = new DisableHighlightingOfInvisibleCharactersAction();
        options.push({ label: action.label, run: () => __awaiter(this, void 0, void 0, function* () {
          return action.runAction(configurationService);
        }) });
      } else if (reason.kind === 2) {
        const action = new DisableHighlightingOfNonBasicAsciiCharactersAction();
        options.push({ label: action.label, run: () => __awaiter(this, void 0, void 0, function* () {
          return action.runAction(configurationService);
        }) });
      } else {
        expectNever(reason);
      }
      const result = yield quickPickService.pick(options, { title: nls.localize("unicodeHighlight.configureUnicodeHighlightOptions", "Configure Unicode Highlight Options") });
      if (result) {
        yield result.run();
      }
    });
  }
}
ShowExcludeOptions.ID = "editor.action.unicodeHighlight.showExcludeOptions";
function excludeCharFromBeingHighlighted(configurationService, charCodes) {
  return __awaiter(this, void 0, void 0, function* () {
    const existingValue = configurationService.getValue(editorOptions.unicodeHighlightConfigKeys.allowedCharacters);
    let value;
    if (typeof existingValue === "object" && existingValue) {
      value = existingValue;
    } else {
      value = {};
    }
    for (const charCode of charCodes) {
      value[String.fromCodePoint(charCode)] = true;
    }
    yield configurationService.updateValue(
      editorOptions.unicodeHighlightConfigKeys.allowedCharacters,
      value,
      1
      /* USER */
    );
  });
}
function excludeLocaleFromBeingHighlighted(configurationService, locales) {
  var _a;
  return __awaiter(this, void 0, void 0, function* () {
    const existingValue = (_a = configurationService.inspect(editorOptions.unicodeHighlightConfigKeys.allowedLocales).user) === null || _a === void 0 ? void 0 : _a.value;
    let value;
    if (typeof existingValue === "object" && existingValue) {
      value = Object.assign({}, existingValue);
    } else {
      value = {};
    }
    for (const locale of locales) {
      value[locale] = true;
    }
    yield configurationService.updateValue(
      editorOptions.unicodeHighlightConfigKeys.allowedLocales,
      value,
      1
      /* USER */
    );
  });
}
function expectNever(value) {
  throw new Error(`Unexpected value: ${value}`);
}
editorExtensions.registerEditorAction(DisableHighlightingOfAmbiguousCharactersAction);
editorExtensions.registerEditorAction(DisableHighlightingOfInvisibleCharactersAction);
editorExtensions.registerEditorAction(DisableHighlightingOfNonBasicAsciiCharactersAction);
editorExtensions.registerEditorAction(ShowExcludeOptions);
editorExtensions.registerEditorContribution(exports.UnicodeHighlighter.ID, exports.UnicodeHighlighter);
hoverTypes.HoverParticipantRegistry.register(exports.UnicodeHighlighterHoverParticipant);
exports.DisableHighlightingInCommentsAction = DisableHighlightingInCommentsAction;
exports.DisableHighlightingInStringsAction = DisableHighlightingInStringsAction;
exports.DisableHighlightingOfAmbiguousCharactersAction = DisableHighlightingOfAmbiguousCharactersAction;
exports.DisableHighlightingOfInvisibleCharactersAction = DisableHighlightingOfInvisibleCharactersAction;
exports.DisableHighlightingOfNonBasicAsciiCharactersAction = DisableHighlightingOfNonBasicAsciiCharactersAction;
exports.ShowExcludeOptions = ShowExcludeOptions;
exports.warningIcon = warningIcon;
