"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.MainThreadLanguages = void 0;
const tslib_1 = require("tslib");
const di_1 = require("@opensumi/di");
const ide_connection_1 = require("@opensumi/ide-connection");
const ide_core_browser_1 = require("@opensumi/ide-core-browser");
const ide_core_common_1 = require("@opensumi/ide-core-common");
const evaluatable_expression_1 = require("@opensumi/ide-debug/lib/browser/editor/evaluatable-expression");
const ide_editor_1 = require("@opensumi/ide-editor");
const browser_1 = require("@opensumi/ide-editor/lib/browser");
const monaco = tslib_1.__importStar(require("@opensumi/ide-monaco"));
const callHierarchy_1 = require("@opensumi/ide-monaco/lib/browser/contrib/callHierarchy");
const tokenizer_1 = require("@opensumi/ide-monaco/lib/browser/contrib/tokenizer");
const typeHierarchy_1 = require("@opensumi/ide-monaco/lib/browser/contrib/typeHierarchy");
const monaco_api_1 = require("@opensumi/ide-monaco/lib/browser/monaco-api");
const languages_1 = require("@opensumi/ide-monaco/lib/browser/monaco-api/languages");
const range_1 = require("@opensumi/monaco-editor-core/esm/vs/editor/common/core/range");
const modes = tslib_1.__importStar(require("@opensumi/monaco-editor-core/esm/vs/editor/common/languages"));
const language_1 = require("@opensumi/monaco-editor-core/esm/vs/editor/common/languages/language");
const standaloneServices_1 = require("@opensumi/monaco-editor-core/esm/vs/editor/standalone/browser/standaloneServices");
const vscode_1 = require("../../../common/vscode");
const converter_1 = require("../../../common/vscode/converter");
const ext_types_1 = require("../../../common/vscode/ext-types");
const model_api_1 = require("../../../common/vscode/model.api");
const utils_1 = require("../../../common/vscode/utils");
const semantic_token_provider_1 = require("./semantic-tokens/semantic-token-provider");
const { extname } = ide_core_common_1.path;
let MainThreadLanguages = class MainThreadLanguages {
    _reviveCodeActionDto(data) {
        if (data) {
            data.forEach((code) => this.reviveWorkspaceEditDto(code.edit));
        }
        return data;
    }
    constructor(rpcProtocol) {
        this.rpcProtocol = rpcProtocol;
        this.disposables = new Map();
        this.languageFeatureEnabled = new ide_core_common_1.LRUMap(200, 100);
        // #endregion InlayHints
        // #region LanguageStatus
        this._status = new Map();
        this.proxy = this.rpcProtocol.getProxy(vscode_1.ExtHostAPIIdentifier.ExtHostLanguages);
    }
    dispose() {
        this.disposables.forEach((disposable) => {
            disposable.dispose();
        });
        this.disposables.clear();
    }
    $unregister(handle) {
        const disposable = this.disposables.get(handle);
        if (disposable) {
            this.disposables.delete(handle);
            disposable.dispose();
        }
    }
    $getLanguages() {
        return this.textmateService.getLanguages().map((l) => l.id);
    }
    async $changeLanguage(resource, languageId) {
        // FIXME: modeService has been deprecated. use languageService instead.
        const languageIdentifier = standaloneServices_1.StandaloneServices.get(language_1.ILanguageService).getLanguageIdByLanguageName(languageId);
        if (!languageIdentifier || languageIdentifier !== languageId) {
            return Promise.reject(new Error(`Unknown language id: ${languageId}`));
        }
        const uri = new ide_core_common_1.URI(ide_core_common_1.URI.revive(resource));
        const ref = await this.documentModelManager.createModelReference(uri);
        try {
            ref.instance.languageId = languageId;
        }
        finally {
            ref.dispose();
        }
    }
    isLanguageFeatureEnabled(model) {
        if (model.uri.scheme === ide_core_common_1.Schemes.inMemory) {
            return false;
        }
        const uriString = model.uri.toString();
        if (!this.languageFeatureEnabled.has(uriString)) {
            this.languageFeatureEnabled.set(uriString, model.getValueLength() <
                (this.preference.get('editor.languageFeatureEnabledMaxSize') || 4 * 1024 * 1024 * 1024));
        }
        return this.languageFeatureEnabled.get(uriString);
    }
    getUniqueLanguages() {
        const languages = [];
        // 会有重复
        const allLanguages = this.textmateService.getLanguages().map((l) => l.id);
        for (const language of allLanguages) {
            if (languages.indexOf(language) === -1) {
                languages.push(language);
            }
        }
        return languages;
    }
    $registerHoverProvider(handle, selector) {
        const languageSelector = (0, converter_1.fromLanguageSelector)(selector);
        const hoverProvider = this.createHoverProvider(handle, languageSelector);
        this.disposables.set(handle, languages_1.languageFeaturesService.hoverProvider.register(selector, hoverProvider));
    }
    createHoverProvider(handle, selector) {
        return {
            provideHover: (model, position, token) => {
                if (!this.matchModel(selector, vscode_1.MonacoModelIdentifier.fromModel(model))) {
                    return undefined;
                }
                if (!this.isLanguageFeatureEnabled(model)) {
                    return undefined;
                }
                const timer = this.reporter.time(ide_core_common_1.REPORT_NAME.PROVIDE_HOVER);
                return this.proxy.$provideHoverWithDuration(handle, model.uri, position, token).then(({ result, _dur }) => {
                    if (result) {
                        timer.timeEnd(extname(model.uri.fsPath), {
                            extDuration: _dur,
                        });
                    }
                    return result;
                });
            },
        };
    }
    isDeflatedSuggestDto(data) {
        return (data[vscode_1.ISuggestDataDtoField.label] ||
            data[vscode_1.ISuggestDataDtoField.kind] ||
            data[vscode_1.ISuggestDataDtoField.kindModifier] ||
            data[vscode_1.ISuggestDataDtoField.detail] ||
            data[vscode_1.ISuggestDataDtoField.documentation] ||
            data[vscode_1.ISuggestDataDtoField.sortText] ||
            data[vscode_1.ISuggestDataDtoField.filterText] ||
            data[vscode_1.ISuggestDataDtoField.preselect] ||
            data[vscode_1.ISuggestDataDtoField.range] ||
            data[vscode_1.ISuggestDataDtoField.insertTextRules] ||
            data[vscode_1.ISuggestDataDtoField.commitCharacters] ||
            data[vscode_1.ISuggestDataDtoField.insertText] ||
            data[vscode_1.ISuggestDataDtoField.command]);
    }
    inflateLabel(label) {
        if (typeof label === 'object') {
            return label;
        }
        const splitted = label.split('~|');
        if (Array.isArray(splitted) && splitted.length > 1) {
            return {
                label: splitted[0],
                description: splitted[1],
                detail: splitted[2],
            };
        }
        return label;
    }
    inflateSuggestDto(defaultRange, data) {
        var _a, _b;
        if (!this.isDeflatedSuggestDto(data)) {
            return data;
        }
        const label = this.inflateLabel(data[vscode_1.ISuggestDataDtoField.label]);
        const dtoRange = data[vscode_1.ISuggestDataDtoField.range];
        return {
            label,
            kind: (_a = data[vscode_1.ISuggestDataDtoField.kind]) !== null && _a !== void 0 ? _a : modes.CompletionItemKind.Property,
            tags: data[vscode_1.ISuggestDataDtoField.kindModifier],
            detail: data[vscode_1.ISuggestDataDtoField.detail],
            documentation: data[vscode_1.ISuggestDataDtoField.documentation],
            sortText: data[vscode_1.ISuggestDataDtoField.sortText],
            filterText: data[vscode_1.ISuggestDataDtoField.filterText],
            preselect: data[vscode_1.ISuggestDataDtoField.preselect],
            insertText: (_b = data[vscode_1.ISuggestDataDtoField.insertText]) !== null && _b !== void 0 ? _b : (typeof label === 'string' ? label : label.label),
            range: Array.isArray(dtoRange) && dtoRange.length === 4
                ? range_1.Range.lift({
                    startLineNumber: dtoRange[0],
                    startColumn: dtoRange[1],
                    endLineNumber: dtoRange[2],
                    endColumn: dtoRange[3],
                })
                : defaultRange,
            insertTextRules: data[vscode_1.ISuggestDataDtoField.insertTextRules],
            commitCharacters: data[vscode_1.ISuggestDataDtoField.commitCharacters],
            additionalTextEdits: data[vscode_1.ISuggestDataDtoField.additionalTextEdits],
            command: data[vscode_1.ISuggestDataDtoField.command],
            _id: data.x,
        };
    }
    $registerCompletionSupport(handle, selector, triggerCharacters, supportsResolveDetails) {
        this.disposables.set(handle, monaco_api_1.monaco.languages.registerCompletionItemProvider((0, converter_1.fromLanguageSelector)(selector), {
            _debugDisplayName: `ext-${handle}`,
            triggerCharacters,
            provideCompletionItems: async (model, position, context, token) => {
                if (!this.isLanguageFeatureEnabled(model)) {
                    return undefined;
                }
                const timer = this.reporter.time(ide_core_common_1.REPORT_NAME.PROVIDE_COMPLETION_ITEMS);
                const result = await this.proxy.$provideCompletionItems(handle, model.uri, position, context, token);
                if (!result) {
                    return undefined;
                }
                if (result[vscode_1.ISuggestResultDtoField.completions].length) {
                    timer.timeEnd(extname(model.uri.fsPath), {
                        extDuration: result.d,
                    });
                }
                const suggestions = result[vscode_1.ISuggestResultDtoField.completions].map((data) => this.inflateSuggestDto(result[vscode_1.ISuggestResultDtoField.defaultRanges], data));
                return {
                    suggestions,
                    duration: result[vscode_1.ISuggestResultDtoField.duration],
                    incomplete: result[vscode_1.ISuggestResultDtoField.isIncomplete] || false,
                    dispose: () => {
                        if (result.x) {
                            setTimeout(() => {
                                this.proxy.$releaseCompletionItems(handle, result.x);
                            }, 0);
                        }
                    },
                };
            },
            resolveCompletionItem: supportsResolveDetails
                ? async (suggestion, token) => {
                    this.reporter.point(ide_core_common_1.REPORT_NAME.RESOLVE_COMPLETION_ITEM);
                    return this.proxy.$resolveCompletionItem(handle, suggestion._id, token).then((result) => {
                        if (!result) {
                            return suggestion;
                        }
                        const newSuggestion = this.inflateSuggestDto(suggestion.range, result);
                        return (0, utils_1.mixin)(suggestion, newSuggestion, true);
                    });
                }
                : undefined,
        }));
    }
    $registerInlineCompletionsSupport(handle, selector, supportsHandleEvents, extensionId, yieldsToExtensionIds) {
        const provider = {
            provideInlineCompletions: async (model, position, context, token) => this.proxy.$provideInlineCompletions(handle, model.uri, position, context, token),
            handleItemDidShow: async (completions, item, updatedInsertText) => {
                if (supportsHandleEvents) {
                    await this.proxy.$handleInlineCompletionDidShow(handle, completions.pid, item.idx, updatedInsertText);
                }
            },
            handlePartialAccept: async (completions, item, acceptedCharacters) => {
                if (supportsHandleEvents) {
                    await this.proxy.$handleInlineCompletionPartialAccept(handle, completions.pid, item.idx, acceptedCharacters);
                }
            },
            freeInlineCompletions: (completions) => {
                this.proxy.$freeInlineCompletionsList(handle, completions.pid);
            },
            groupId: extensionId,
            yieldsToGroupIds: yieldsToExtensionIds,
            toString() {
                return `InlineCompletionsProvider(${extensionId})`;
            },
        };
        this.disposables.set(handle, monaco_api_1.monaco.languages.registerInlineCompletionsProvider((0, converter_1.fromLanguageSelector)(selector), provider));
    }
    $registerInlineEditProvider(handle, selector, extensionId, displayName) {
        const provider = {
            displayName,
            provideInlineEdit: async (model, context, token) => this.proxy.$provideInlineEdit(handle, model.uri, context, token),
            freeInlineEdit: (edit) => {
                this.proxy.$freeInlineEdit(handle, edit.pid);
            },
        };
        this.disposables.set(handle, monaco_api_1.monaco.languages.registerInlineEditProvider((0, converter_1.fromLanguageSelector)(selector), provider));
    }
    matchLanguage(selector, languageId) {
        if (Array.isArray(selector)) {
            return selector.some((filter) => this.matchLanguage(filter, languageId));
        }
        if ((0, model_api_1.isDocumentFilter)(selector)) {
            if (!selector.language && (selector.pattern || selector.scheme)) {
                return true;
            }
            return (selector === null || selector === void 0 ? void 0 : selector.language) === languageId;
        }
        return selector === languageId;
    }
    matchModel(selector, model) {
        if (Array.isArray(selector)) {
            return selector.some((filter) => this.matchModel(filter, model));
        }
        if ((0, model_api_1.isDocumentFilter)(selector)) {
            if (!!selector.language && selector.language !== model.languageId) {
                return false;
            }
            if (!!selector.scheme && selector.scheme !== model.uri.scheme) {
                return false;
            }
            if (!!selector.pattern && !(0, vscode_1.testGlob)(selector.pattern, model.uri.path)) {
                return false;
            }
            return true;
        }
        return selector === model.languageId;
    }
    $registerDefinitionProvider(handle, selector) {
        const languageSelector = (0, converter_1.fromLanguageSelector)(selector);
        if (!languageSelector) {
            return;
        }
        const definitionProvider = this.createDefinitionProvider(handle, languageSelector);
        this.disposables.set(handle, monaco_api_1.monaco.languages.registerDefinitionProvider(languageSelector, definitionProvider));
    }
    $registerDeclarationProvider(handle, selector) {
        const languageSelector = (0, converter_1.fromLanguageSelector)(selector);
        if (!languageSelector) {
            return;
        }
        // const definitionProvider = this.createDefinitionProvider(handle, languageSelector);
        const disposable = new ide_core_common_1.DisposableCollection();
        for (const language of this.getUniqueLanguages()) {
            if (this.matchLanguage(languageSelector, language)) {
                // disposable.push(monacoApi.languages.registerDeclarationProvider(language, definitionProvider));
            }
        }
        this.disposables.set(handle, disposable);
    }
    createDefinitionProvider(handle, selector) {
        return {
            provideDefinition: async (model, position, token) => {
                if (!this.matchModel(selector, vscode_1.MonacoModelIdentifier.fromModel(model))) {
                    return undefined;
                }
                if (!this.isLanguageFeatureEnabled(model)) {
                    return undefined;
                }
                const timer = this.reporter.time(ide_core_common_1.REPORT_NAME.PROVIDE_DEFINITION);
                const { result, _dur } = await this.proxy.$provideDefinitionWithDuration(handle, model.uri, position, token);
                if (!result) {
                    return undefined;
                }
                timer.timeEnd(extname(model.uri.fsPath), {
                    extDuration: _dur,
                });
                if (Array.isArray(result)) {
                    const definitionLinks = [];
                    for (const item of result) {
                        definitionLinks.push({ ...item, uri: monaco.Uri.revive(item.uri) });
                    }
                    return definitionLinks;
                }
                else {
                    // single Location
                    return {
                        uri: monaco.Uri.revive(result.uri),
                        range: result.range,
                    };
                }
            },
        };
    }
    $registerTypeDefinitionProvider(handle, selector) {
        const languageSelector = (0, converter_1.fromLanguageSelector)(selector);
        if (!languageSelector) {
            return;
        }
        const typeDefinitionProvider = this.createTypeDefinitionProvider(handle, languageSelector);
        this.disposables.set(handle, monaco_api_1.monaco.languages.registerTypeDefinitionProvider(languageSelector, typeDefinitionProvider));
    }
    createTypeDefinitionProvider(handle, selector) {
        return {
            provideTypeDefinition: (model, position, token) => {
                if (!this.isLanguageFeatureEnabled(model)) {
                    return undefined;
                }
                if (!this.matchModel(selector, vscode_1.MonacoModelIdentifier.fromModel(model))) {
                    return undefined;
                }
                const timer = this.reporter.time(ide_core_common_1.REPORT_NAME.PROVIDE_TYPE_DEFINITION);
                return this.proxy.$provideTypeDefinition(handle, model.uri, position, token).then((result) => {
                    if (!result) {
                        return undefined;
                    }
                    timer.timeEnd(extname(model.uri.fsPath));
                    if (Array.isArray(result)) {
                        const definitionLinks = [];
                        for (const item of result) {
                            definitionLinks.push({ ...item, uri: monaco.Uri.revive(item.uri) });
                        }
                        return definitionLinks;
                    }
                    else {
                        // single Location
                        return {
                            uri: monaco.Uri.revive(result.uri),
                            range: result.range,
                        };
                    }
                });
            },
        };
    }
    $registerFoldingRangeProvider(handle, selector, eventHandle) {
        const languageSelector = (0, converter_1.fromLanguageSelector)(selector);
        if (!languageSelector) {
            return;
        }
        const provider = this.createFoldingRangeProvider(handle, languageSelector);
        if (typeof eventHandle === 'number') {
            const emitter = new ide_core_common_1.Emitter();
            this.disposables.set(eventHandle, emitter);
            provider.onDidChange = emitter.event;
        }
        this.disposables.set(handle, monaco_api_1.monaco.languages.registerFoldingRangeProvider(languageSelector, provider));
    }
    $emitFoldingRangeEvent(eventHandle, event) {
        const obj = this.disposables.get(eventHandle);
        if (obj instanceof ide_core_common_1.Emitter) {
            obj.fire(event);
        }
    }
    createFoldingRangeProvider(handle, selector) {
        return {
            provideFoldingRanges: (model, context, token) => {
                if (!this.isLanguageFeatureEnabled(model)) {
                    return undefined;
                }
                if (!this.matchModel(selector, vscode_1.MonacoModelIdentifier.fromModel(model))) {
                    return undefined;
                }
                const timer = this.reporter.time(ide_core_common_1.REPORT_NAME.PROVIDE_FOLDING_RANGES);
                return this.proxy.$provideFoldingRange(handle, model.uri, context, token).then((v) => {
                    if (v) {
                        timer.timeEnd(extname(model.uri.fsPath));
                    }
                    return v;
                });
            },
        };
    }
    $registerDocumentColorProvider(handle, selector) {
        const languageSelector = (0, converter_1.fromLanguageSelector)(selector);
        if (!languageSelector) {
            return;
        }
        const colorProvider = this.createColorProvider(handle, languageSelector);
        this.disposables.set(handle, monaco_api_1.monaco.languages.registerColorProvider(languageSelector, colorProvider));
    }
    createColorProvider(handle, selector) {
        return {
            provideDocumentColors: (model, token) => {
                if (!this.isLanguageFeatureEnabled(model)) {
                    return undefined;
                }
                if (!this.matchModel(selector, vscode_1.MonacoModelIdentifier.fromModel(model))) {
                    return undefined;
                }
                const timer = this.reporter.time(ide_core_common_1.REPORT_NAME.PROVIDE_DOCUMENT_COLORS);
                return this.proxy.$provideDocumentColors(handle, model.uri, token).then((documentColors) => {
                    timer.timeEnd(extname(model.uri.fsPath));
                    return documentColors.map((documentColor) => {
                        const [red, green, blue, alpha] = documentColor.color;
                        const color = {
                            red,
                            green,
                            blue,
                            alpha,
                        };
                        return {
                            color,
                            range: documentColor.range,
                        };
                    });
                });
            },
            provideColorPresentations: (model, colorInfo, token) => {
                if (!this.isLanguageFeatureEnabled(model)) {
                    return undefined;
                }
                const timer = this.reporter.time(ide_core_common_1.REPORT_NAME.PROVIDE_COLOR_PRESENTATIONS);
                return this.proxy
                    .$provideColorPresentations(handle, model.uri, {
                    color: [colorInfo.color.red, colorInfo.color.green, colorInfo.color.blue, colorInfo.color.alpha],
                    range: colorInfo.range,
                }, token)
                    .then((v) => {
                    if (v) {
                        timer.timeEnd(extname(model.uri.fsPath));
                    }
                    return v;
                });
            },
        };
    }
    $registerDocumentHighlightProvider(handle, selector) {
        const languageSelector = (0, converter_1.fromLanguageSelector)(selector);
        if (!languageSelector) {
            return;
        }
        const documentHighlightProvider = this.createDocumentHighlightProvider(handle, languageSelector);
        this.disposables.set(handle, monaco_api_1.monaco.languages.registerDocumentHighlightProvider(languageSelector, documentHighlightProvider));
    }
    createDocumentHighlightProvider(handle, selector) {
        return {
            provideDocumentHighlights: (model, position, token) => {
                if (!this.isLanguageFeatureEnabled(model)) {
                    return undefined;
                }
                if (!this.matchModel(selector, vscode_1.MonacoModelIdentifier.fromModel(model))) {
                    return undefined;
                }
                const timer = this.reporter.time(ide_core_common_1.REPORT_NAME.PROVIDE_DOCUMENT_HIGHLIGHTS);
                return this.proxy.$provideDocumentHighlights(handle, model.uri, position, token).then((result) => {
                    if (!result) {
                        return undefined;
                    }
                    if (Array.isArray(result)) {
                        timer.timeEnd(extname(model.uri.fsPath));
                        const highlights = [];
                        for (const item of result) {
                            highlights.push({
                                ...item,
                                kind: item.kind !== undefined ? item.kind : monaco.languages.DocumentHighlightKind.Text,
                            });
                        }
                        return highlights;
                    }
                    return undefined;
                });
            },
        };
    }
    $registerDocumentFormattingProvider(handle, extension, selector) {
        const languageSelector = (0, converter_1.fromLanguageSelector)(selector);
        if (!languageSelector) {
            return;
        }
        const documentFormattingEditProvider = this.createDocumentFormattingEditProvider(handle, extension, languageSelector);
        this.disposables.set(handle, monaco_api_1.monaco.languages.registerDocumentFormattingEditProvider(languageSelector, documentFormattingEditProvider));
    }
    createDocumentFormattingEditProvider(handle, extension, selector) {
        return {
            displayName: extension.displayName,
            extensionId: extension.id,
            provideDocumentFormattingEdits: async (model, options) => {
                if (!this.isLanguageFeatureEnabled(model)) {
                    return undefined;
                }
                if (!this.matchModel(selector, vscode_1.MonacoModelIdentifier.fromModel(model))) {
                    return undefined;
                }
                const timer = this.reporter.time(ide_core_common_1.REPORT_NAME.PROVIDE_DOCUMENT_FORMATTING_EDITS);
                return this.proxy.$provideDocumentFormattingEdits(handle, model.uri, options).then((result) => {
                    timer.timeEnd(extname(model.uri.fsPath));
                    if (!result) {
                        return undefined;
                    }
                    return result;
                });
            },
        };
    }
    $registerRangeFormattingProvider(handle, extension, selector) {
        const languageSelector = (0, converter_1.fromLanguageSelector)(selector);
        if (!languageSelector) {
            return;
        }
        const documentHighlightProvider = this.createDocumentRangeFormattingEditProvider(handle, extension, languageSelector);
        this.disposables.set(handle, monaco_api_1.monaco.languages.registerDocumentRangeFormattingEditProvider(languageSelector, documentHighlightProvider));
    }
    createDocumentRangeFormattingEditProvider(handle, extension, selector) {
        return {
            displayName: extension.displayName,
            extensionId: extension.id,
            provideDocumentRangeFormattingEdits: async (model, range, options) => {
                if (!this.isLanguageFeatureEnabled(model)) {
                    return undefined;
                }
                if (!this.matchModel(selector, vscode_1.MonacoModelIdentifier.fromModel(model))) {
                    return undefined;
                }
                const timer = this.reporter.time(ide_core_common_1.REPORT_NAME.PROVIDE_DOCUMENT_RANGE_FORMATTING_EDITS);
                return this.proxy.$provideDocumentRangeFormattingEdits(handle, model.uri, range, options).then((result) => {
                    timer.timeEnd(extname(model.uri.fsPath));
                    if (!result) {
                        return undefined;
                    }
                    return result;
                });
            },
        };
    }
    $registerOnTypeFormattingProvider(handle, selector, autoFormatTriggerCharacters) {
        const languageSelector = (0, converter_1.fromLanguageSelector)(selector);
        if (!languageSelector) {
            return;
        }
        const onTypeFormattingProvider = this.createOnTypeFormattingProvider(handle, languageSelector, autoFormatTriggerCharacters);
        this.disposables.set(handle, monaco_api_1.monaco.languages.registerOnTypeFormattingEditProvider(languageSelector, onTypeFormattingProvider));
    }
    createOnTypeFormattingProvider(handle, selector, autoFormatTriggerCharacters) {
        return {
            autoFormatTriggerCharacters,
            provideOnTypeFormattingEdits: async (model, position, ch, options) => {
                if (!this.isLanguageFeatureEnabled(model)) {
                    return undefined;
                }
                if (!this.matchModel(selector, vscode_1.MonacoModelIdentifier.fromModel(model))) {
                    return undefined;
                }
                const timer = this.reporter.time(ide_core_common_1.REPORT_NAME.PROVIDE_ON_TYPE_FORMATTING_EDITS);
                return this.proxy
                    .$provideOnTypeFormattingEditsWithDuration(handle, model.uri, position, ch, options)
                    .then(({ result, _dur }) => {
                    if (result) {
                        timer.timeEnd(extname(model.uri.fsPath), {
                            extDuration: _dur,
                        });
                    }
                    return result;
                });
            },
        };
    }
    $registerCodeLensSupport(handle, selector, eventHandle) {
        const languageSelector = (0, converter_1.fromLanguageSelector)(selector);
        if (!languageSelector) {
            return;
        }
        const lensProvider = this.createCodeLensProvider(handle, languageSelector);
        if (typeof eventHandle === 'number') {
            const emitter = new ide_core_common_1.Emitter();
            this.disposables.set(eventHandle, emitter);
            lensProvider.onDidChange = emitter.event;
        }
        this.disposables.set(handle, monaco_api_1.monaco.languages.registerCodeLensProvider(languageSelector, lensProvider));
    }
    createCodeLensProvider(handle, selector) {
        return {
            provideCodeLenses: (model, token) => {
                if (!this.isLanguageFeatureEnabled(model)) {
                    return undefined;
                }
                const timer = this.reporter.time(ide_core_common_1.REPORT_NAME.PROVIDE_CODE_LENSES);
                return this.proxy.$provideCodeLenses(handle, model.uri, token).then((dto) => {
                    if (dto) {
                        timer.timeEnd(extname(model.uri.fsPath));
                    }
                    return {
                        lenses: (dto === null || dto === void 0 ? void 0 : dto.lenses) || [],
                        dispose: () => (dto === null || dto === void 0 ? void 0 : dto.cacheId) && this.proxy.$releaseCodeLens(handle, dto.cacheId),
                    };
                });
            },
            resolveCodeLens: async (model, codeLens, token) => {
                if (!this.isLanguageFeatureEnabled(model)) {
                    return undefined;
                }
                this.reporter.point(ide_core_common_1.REPORT_NAME.RESOLVE_CODE_LENS);
                return this.proxy.$resolveCodeLens(handle, codeLens, token).then((v) => v);
            },
        };
    }
    $emitCodeLensEvent(eventHandle, event) {
        // FIXME: 由于 IDisposable 本身不是 Emitter 的实例，因此以下代码并不会执行
        const obj = this.disposables.get(eventHandle);
        if (obj instanceof ide_core_common_1.Emitter) {
            obj.fire(event);
        }
    }
    $clearDiagnostics(id) {
        this.markerManager.clearMarkers(id);
    }
    $changeDiagnostics(id, delta) {
        for (const [uriString, markers] of delta) {
            this.markerManager.updateMarkers(id, uriString, markers);
        }
    }
    $registerImplementationProvider(handle, selector) {
        const languageSelector = (0, converter_1.fromLanguageSelector)(selector);
        if (!languageSelector) {
            return;
        }
        const implementationProvider = this.createImplementationProvider(handle, languageSelector);
        this.disposables.set(handle, monaco_api_1.monaco.languages.registerImplementationProvider(languageSelector, implementationProvider));
    }
    $registerDocumentLinkProvider(handle, selector, supportsResolve) {
        const languageSelector = (0, converter_1.fromLanguageSelector)(selector);
        if (!languageSelector) {
            return;
        }
        const linkProvider = this.createLinkProvider(handle, supportsResolve);
        this.disposables.set(handle, monaco_api_1.monaco.languages.registerLinkProvider(languageSelector, linkProvider));
    }
    createImplementationProvider(handle, selector) {
        return {
            provideImplementation: (model, position, token) => {
                if (!this.isLanguageFeatureEnabled(model)) {
                    return undefined;
                }
                if (!this.matchModel(selector, vscode_1.MonacoModelIdentifier.fromModel(model))) {
                    return undefined;
                }
                const timer = this.reporter.time(ide_core_common_1.REPORT_NAME.PROVIDE_IMPLEMENTATION);
                return this.proxy.$provideImplementationWithDuration(handle, model.uri, position).then(({ result, _dur }) => {
                    if (!result) {
                        return undefined;
                    }
                    timer.timeEnd(extname(model.uri.fsPath), {
                        extDuration: _dur,
                    });
                    if (Array.isArray(result)) {
                        // using DefinitionLink because Location is mandatory part of DefinitionLink
                        const definitionLinks = [];
                        for (const item of result) {
                            definitionLinks.push({ ...item, uri: monaco.Uri.revive(item.uri) });
                        }
                        return definitionLinks;
                    }
                    else {
                        // single Location
                        return {
                            uri: monaco.Uri.revive(result.uri),
                            range: result.range,
                        };
                    }
                });
            },
        };
    }
    $registerQuickFixProvider(handle, selector, metadata, displayName, supportResolve) {
        const languageSelector = (0, converter_1.fromLanguageSelector)(selector);
        if (!languageSelector) {
            return;
        }
        const quickFixProvider = this.createQuickFixProvider(handle, languageSelector, metadata, displayName, supportResolve);
        this.disposables.set(handle, languages_1.languageFeaturesService.codeActionProvider.register(languageSelector, quickFixProvider));
    }
    createQuickFixProvider(handle, selector, metadata, displayName, supportsResolve) {
        const provider = {
            provideCodeActions: async (model, rangeOrSelection, monacoContext, token) => {
                if (!this.isLanguageFeatureEnabled(model)) {
                    return undefined;
                }
                if (!this.matchModel(selector, vscode_1.MonacoModelIdentifier.fromModel(model))) {
                    return undefined;
                }
                const timer = this.reporter.time(ide_core_common_1.REPORT_NAME.PROVIDE_CODE_ACTIONS);
                const listDto = await this.proxy
                    .$provideCodeActions(handle, model.uri, rangeOrSelection, monacoContext, token)
                    .then((v) => {
                    timer.timeEnd(extname(model.uri.fsPath));
                    return v;
                });
                if (!listDto) {
                    return undefined;
                }
                return {
                    actions: this._reviveCodeActionDto(listDto.actions),
                    dispose: () => {
                        if (typeof listDto.cacheId === 'number') {
                            this.proxy.$releaseCodeActions(handle, listDto.cacheId);
                        }
                    },
                };
            },
            documentation: metadata.documentation,
            providedCodeActionKinds: metadata.providedKinds,
            displayName,
        };
        if (supportsResolve) {
            provider.resolveCodeAction = async (codeAction, token) => {
                const data = await this.proxy.$resolveCodeAction(handle, codeAction.cacheId, token);
                codeAction.edit = this.reviveWorkspaceEditDto(data);
                return codeAction;
            };
        }
        return provider;
    }
    createLinkProvider(handle, supportResolve) {
        const provider = {
            provideLinks: (model, token) => {
                if (!this.isLanguageFeatureEnabled(model)) {
                    return undefined;
                }
                const timer = this.reporter.time(ide_core_common_1.REPORT_NAME.PROVIDE_LINKS);
                return this.proxy.$provideDocumentLinks(handle, model.uri, token).then((linksDto) => {
                    if (!linksDto) {
                        return undefined;
                    }
                    timer.timeEnd(extname(model.uri.fsPath));
                    const links = linksDto.links.map((link) => this.reviveLink(link));
                    return {
                        links,
                        dispose: () => {
                            if (linksDto.id) {
                                this.proxy.$releaseDocumentLinks(handle, linksDto.id);
                            }
                        },
                    };
                });
            },
        };
        if (supportResolve) {
            provider.resolveLink = (link, token) => {
                const dto = link;
                if (!dto.cacheId) {
                    return link;
                }
                return this.proxy.$resolveDocumentLink(handle, dto.cacheId, token).then((v) => {
                    if (!v) {
                        return undefined;
                    }
                    return this.reviveLink(v);
                });
            };
        }
        return provider;
    }
    reviveLink(data) {
        if (data.url && typeof data.url !== 'string') {
            data.url = ide_core_common_1.URI.revive(data.url);
        }
        return data;
    }
    $setLanguageConfiguration(handle, languageId, configuration) {
        const config = {
            comments: configuration.comments,
            brackets: configuration.brackets,
            wordPattern: (0, utils_1.reviveRegExp)(configuration.wordPattern),
            indentationRules: (0, utils_1.reviveIndentationRule)(configuration.indentationRules),
            onEnterRules: (0, utils_1.reviveOnEnterRules)(configuration.onEnterRules),
            autoClosingPairs: configuration.autoClosingPairs,
        };
        this.disposables.set(handle, monaco_api_1.monaco.languages.setLanguageConfiguration(languageId, config));
    }
    $registerReferenceProvider(handle, selector) {
        const languageSelector = (0, converter_1.fromLanguageSelector)(selector);
        if (!languageSelector) {
            return;
        }
        const referenceProvider = this.createReferenceProvider(handle, languageSelector);
        this.disposables.set(handle, monaco_api_1.monaco.languages.registerReferenceProvider(languageSelector, referenceProvider));
    }
    createReferenceProvider(handle, selector) {
        return {
            provideReferences: (model, position, context, token) => {
                if (!this.isLanguageFeatureEnabled(model)) {
                    return undefined;
                }
                if (!this.matchModel(selector, vscode_1.MonacoModelIdentifier.fromModel(model))) {
                    return undefined;
                }
                const timer = this.reporter.time(ide_core_common_1.REPORT_NAME.PROVIDE_REFERENCES);
                return this.proxy
                    .$provideReferencesWithDuration(handle, model.uri, position, context, token)
                    .then(({ result, _dur }) => {
                    if (!result) {
                        return undefined;
                    }
                    if (Array.isArray(result)) {
                        timer.timeEnd(extname(model.uri.fsPath), {
                            extDuration: _dur,
                        });
                        const references = [];
                        for (const item of result) {
                            references.push({ ...item, uri: monaco.Uri.revive(item.uri) });
                        }
                        return references;
                    }
                    return undefined;
                });
            },
        };
    }
    $registerWorkspaceSymbolProvider(handle) {
        const workspaceSymbolProvider = this.createWorkspaceSymbolProvider(handle);
        this.disposables.set(handle, this.languageService.registerWorkspaceSymbolProvider(workspaceSymbolProvider));
    }
    createWorkspaceSymbolProvider(handle) {
        return {
            provideWorkspaceSymbols: (params, token) => this.proxy.$provideWorkspaceSymbols(handle, params.query, token),
            resolveWorkspaceSymbol: (symbol, token) => this.proxy.$resolveWorkspaceSymbol(handle, symbol, token),
        };
    }
    $registerOutlineSupport(handle, selector) {
        const languageSelector = (0, converter_1.fromLanguageSelector)(selector);
        if (!languageSelector) {
            return;
        }
        const symbolProvider = this.createDocumentSymbolProvider(handle, languageSelector);
        this.disposables.set(handle, monaco_api_1.monaco.languages.registerDocumentSymbolProvider(languageSelector, symbolProvider));
    }
    createDocumentSymbolProvider(handle, selector) {
        return {
            provideDocumentSymbols: (model, token) => {
                if (!this.isLanguageFeatureEnabled(model)) {
                    return undefined;
                }
                const timer = this.reporter.time(ide_core_common_1.REPORT_NAME.PROVIDE_DOCUMENT_SYMBOLS);
                return this.proxy.$provideDocumentSymbols(handle, model.uri, token).then((v) => {
                    if (v) {
                        timer.timeEnd(extname(model.uri.fsPath));
                    }
                    return v;
                });
            },
        };
    }
    $registerSignatureHelpProvider(handle, selector, metadata) {
        const languageSelector = (0, converter_1.fromLanguageSelector)(selector);
        if (!languageSelector) {
            return;
        }
        const signatureHelpProvider = this.createSignatureHelpProvider(handle, languageSelector, metadata);
        this.disposables.set(handle, monaco_api_1.monaco.languages.registerSignatureHelpProvider(languageSelector, signatureHelpProvider));
    }
    createSignatureHelpProvider(handle, selector, metadata) {
        return {
            signatureHelpTriggerCharacters: metadata.triggerCharacters,
            signatureHelpRetriggerCharacters: metadata.retriggerCharacters,
            provideSignatureHelp: (model, position, token, context) => {
                if (!this.isLanguageFeatureEnabled(model)) {
                    return undefined;
                }
                if (!this.matchModel(selector, vscode_1.MonacoModelIdentifier.fromModel(model))) {
                    return undefined;
                }
                const timer = this.reporter.time(ide_core_common_1.REPORT_NAME.PROVIDE_SIGNATURE_HELP);
                return this.proxy.$provideSignatureHelp(handle, model.uri, position, context, token).then((v) => {
                    if (!v) {
                        return undefined;
                    }
                    timer.timeEnd(extname(model.uri.fsPath));
                    return {
                        value: v,
                        dispose: () => v.id && this.proxy.$releaseSignatureHelp(handle, v.id),
                    };
                });
            },
        };
    }
    $registerRenameProvider(handle, selector, supportsResolveLocation) {
        const languageSelector = (0, converter_1.fromLanguageSelector)(selector);
        if (!languageSelector) {
            return;
        }
        const renameProvider = this.createRenameProvider(handle, languageSelector, supportsResolveLocation);
        this.disposables.set(handle, monaco_api_1.monaco.languages.registerRenameProvider(languageSelector, renameProvider));
    }
    createRenameProvider(handle, selector, supportsResolveLocation) {
        return {
            provideRenameEdits: (model, position, newName, token) => {
                if (!this.isLanguageFeatureEnabled(model)) {
                    return undefined;
                }
                if (!this.matchModel(selector, vscode_1.MonacoModelIdentifier.fromModel(model))) {
                    return undefined;
                }
                const timer = this.reporter.time(ide_core_common_1.REPORT_NAME.PROVIDE_RENAME_EDITS);
                return this.proxy.$provideRenameEdits(handle, model.uri, position, newName, token).then((v) => {
                    if (v) {
                        timer.timeEnd(extname(model.uri.fsPath));
                    }
                    return this.reviveWorkspaceEditDto(v);
                });
            },
            resolveRenameLocation: supportsResolveLocation
                ? (model, position, token) => {
                    if (!this.isLanguageFeatureEnabled(model)) {
                        return undefined;
                    }
                    if (!this.matchModel(selector, vscode_1.MonacoModelIdentifier.fromModel(model))) {
                        return undefined;
                    }
                    return this.proxy.$resolveRenameLocation(handle, model.uri, position, token).then((v) => v);
                }
                : undefined,
        };
    }
    createNewSymbolNamesProvider(handle, selector) {
        return {
            provideNewSymbolNames: (model, range, triggerKind, token) => {
                if (!this.isLanguageFeatureEnabled(model)) {
                    return undefined;
                }
                if (!this.matchModel(selector, vscode_1.MonacoModelIdentifier.fromModel(model))) {
                    return undefined;
                }
                const timer = this.reporter.time(ide_core_common_1.REPORT_NAME.PROVIDE_NEW_SYMBOL_NAMES);
                return this.proxy.$provideNewSymbolNames(handle, model.uri, range, triggerKind, token).then((v) => {
                    if (v) {
                        timer.timeEnd(extname(model.uri.fsPath));
                    }
                    return v;
                });
            },
        };
    }
    $registerNewSymbolNamesProvider(handle, selector) {
        const languageSelector = (0, converter_1.fromLanguageSelector)(selector);
        if (!languageSelector) {
            return;
        }
        const newSymbolsProvider = this.createNewSymbolNamesProvider(handle, languageSelector);
        this.disposables.set(handle, monaco_api_1.monaco.languages.registerNewSymbolNameProvider(languageSelector, newSymbolsProvider));
    }
    /**
     * 将 IWorkspaceEditDto 转为 monaco-editor 中的 WorkspaceEdit
     */
    reviveWorkspaceEditDto(data) {
        if (data && data.edits) {
            for (const edit of data.edits) {
                if (typeof edit.resource === 'object') {
                    edit.resource = monaco.Uri.revive(edit.resource);
                }
                else {
                    edit.newResource = monaco.Uri.revive(edit.newResource);
                    edit.oldResource = monaco.Uri.revive(edit.oldResource);
                }
            }
        }
        return data;
    }
    $registerSelectionRangeProvider(handle, selector) {
        const languageSelector = (0, converter_1.fromLanguageSelector)(selector);
        if (!languageSelector) {
            return;
        }
        const selectionRangeProvider = this.createSelectionProvider(handle, languageSelector);
        this.disposables.set(handle, monaco_api_1.monaco.languages.registerSelectionRangeProvider(languageSelector, selectionRangeProvider));
    }
    createSelectionProvider(handle, selector) {
        return {
            provideSelectionRanges: (model, positions, token) => {
                if (!this.matchModel(selector, vscode_1.MonacoModelIdentifier.fromModel(model))) {
                    return undefined;
                }
                if (!this.isLanguageFeatureEnabled(model)) {
                    return undefined;
                }
                const timer = this.reporter.time(ide_core_common_1.REPORT_NAME.PROVIDE_SELECTION_RANGES);
                return this.proxy.$provideSelectionRanges(handle, model.uri, positions, token).then((v) => {
                    timer.timeEnd(extname(model.uri.fsPath));
                    return v;
                });
            },
        };
    }
    $registerCallHierarchyProvider(handle, selector) {
        const languageSelector = (0, converter_1.fromLanguageSelector)(selector);
        const provider = this.createCallHierarchyProvider(handle, languageSelector);
        // @ts-ignore
        this.callHierarchyService.registerCallHierarchyProvider(selector, provider);
    }
    reviveCallHierarchyItemDto(data) {
        if (data) {
            data.uri = ide_core_common_1.URI.revive(data.uri);
        }
        return data;
    }
    createCallHierarchyProvider(handle, selector) {
        return {
            prepareCallHierarchy: async (document, position, token) => {
                const items = await this.proxy.$prepareCallHierarchy(handle, document.uri, position, token);
                if (!items) {
                    return undefined;
                }
                return {
                    dispose: () => {
                        for (const item of items) {
                            this.proxy.$releaseCallHierarchy(handle, item._sessionId);
                        }
                    },
                    roots: items.map(this.reviveCallHierarchyItemDto),
                };
            },
            provideOutgoingCalls: async (item, token) => {
                const outgoing = await this.proxy.$provideCallHierarchyOutgoingCalls(handle, item._sessionId, item._itemId, token);
                if (!outgoing) {
                    return outgoing;
                }
                outgoing.forEach((value) => {
                    value.to = this.reviveCallHierarchyItemDto(value.to);
                });
                return outgoing;
            },
            provideIncomingCalls: async (item, token) => {
                const incoming = await this.proxy.$provideCallHierarchyIncomingCalls(handle, item._sessionId, item._itemId, token);
                if (!incoming) {
                    return incoming;
                }
                incoming.forEach((value) => {
                    value.from = this.reviveCallHierarchyItemDto(value.from);
                });
                return incoming;
            },
        };
    }
    // --- type hierarchy
    $registerTypeHierarchyProvider(handle, selector) {
        const languageSelector = (0, converter_1.fromLanguageSelector)(selector);
        const provider = this.createTypeHierarchyProvider(handle, languageSelector);
        this.typeHierarchyService.registerTypeHierarchyProvider(selector, provider);
    }
    createTypeHierarchyProvider(handle, selector) {
        return {
            prepareTypeHierarchy: async (document, position, token) => {
                const items = await this.proxy.$prepareTypeHierarchy(handle, document.uri, position, token);
                if (!items) {
                    return undefined;
                }
                return {
                    dispose: () => {
                        for (const item of items) {
                            this.proxy.$releaseTypeHierarchy(handle, item._sessionId);
                        }
                    },
                    roots: items.map(this.reviveTypeHierarchyItemDto),
                };
            },
            provideSupertypes: async (item, token) => {
                const supertypes = await this.proxy.$provideTypeHierarchySupertypes(handle, item._sessionId, item._itemId, token);
                if (!supertypes) {
                    return supertypes;
                }
                return supertypes.map(this.reviveTypeHierarchyItemDto);
            },
            provideSubtypes: async (item, token) => {
                const subtypes = await this.proxy.$provideTypeHierarchySubtypes(handle, item._sessionId, item._itemId, token);
                if (!subtypes) {
                    return subtypes;
                }
                return subtypes.map(this.reviveTypeHierarchyItemDto);
            },
        };
    }
    reviveTypeHierarchyItemDto(data) {
        if (data) {
            data.uri = ide_core_common_1.URI.revive(data.uri);
        }
        return data;
    }
    // #region Semantic Tokens
    $registerDocumentSemanticTokensProvider(handle, selector, legend) {
        const provider = new semantic_token_provider_1.DocumentSemanticTokensProvider(this.proxy, handle, legend);
        this.disposables.set(handle, languages_1.languageFeaturesService.documentSemanticTokensProvider.register((0, converter_1.fromLanguageSelector)(selector), provider));
    }
    $registerDocumentRangeSemanticTokensProvider(handle, selector, legend) {
        const provider = new semantic_token_provider_1.DocumentRangeSemanticTokensProviderImpl(this.proxy, handle, legend);
        this.disposables.set(handle, languages_1.languageFeaturesService.documentRangeSemanticTokensProvider.register((0, converter_1.fromLanguageSelector)(selector), provider));
    }
    // #endregion Semantic Tokens
    // #region EvaluatableExpression
    $registerEvaluatableExpressionProvider(handler, selector) {
        const provider = {
            provideEvaluatableExpression: (model, position, token) => this.proxy.$provideEvaluatableExpression(handler, model.uri, position, token),
        };
        this.disposables.set(handler, this.evaluatableExpressionService.registerEvaluatableExpressionProvider(selector, provider));
    }
    // #endregion EvaluatableExpression
    // #region Inline Values
    $registerInlineValuesProvider(handler, selector, eventHandle) {
        const provider = {
            provideInlineValues: (model, viewPort, context, token) => this.proxy.$provideInlineValues(handler, model.uri, viewPort, context, token),
        };
        if (typeof eventHandle === 'number') {
            const emitter = new ide_core_common_1.Emitter();
            this.disposables.set(eventHandle, emitter);
            provider.onDidChangeInlineValues = emitter.event;
        }
        this.disposables.set(handler, languages_1.languageFeaturesService.inlineValuesProvider.register(selector, provider));
    }
    $emitInlineValuesEvent(eventHandle, event) {
        const obj = this.disposables.get(eventHandle);
        if (obj instanceof ide_core_common_1.Emitter) {
            obj.fire(event);
        }
    }
    // #endregion Inline Values
    // #region Linked Editing Range
    $registerLinkedEditingRangeProvider(handle, selector) {
        const languageSelector = (0, converter_1.fromLanguageSelector)(selector);
        languages_1.languageFeaturesService.linkedEditingRangeProvider.register(languageSelector, {
            provideLinkedEditingRanges: async (model, position, token) => {
                const res = await this.proxy.$provideLinkedEditingRanges(handle, model.uri, position, token);
                if (res) {
                    return {
                        ranges: res.ranges,
                        wordPattern: res.wordPattern ? (0, utils_1.reviveRegExp)(res.wordPattern) : undefined,
                    };
                }
                return undefined;
            },
        });
    }
    // #endregion Linked Editing Range
    // #region InlayHints
    $registerInlayHintsProvider(handle, selector, supportsResolve, eventHandle) {
        const provider = {
            provideInlayHints: async (model, range, token) => {
                const result = await this.proxy.$provideInlayHints(handle, model.uri, range, token);
                if (!result) {
                    return;
                }
                return {
                    hints: (0, ide_core_common_1.revive)(result === null || result === void 0 ? void 0 : result.hints),
                    dispose: () => {
                        if (result.cacheId) {
                            this.proxy.$releaseInlayHints(handle, result.cacheId);
                        }
                    },
                };
            },
        };
        if (supportsResolve) {
            provider.resolveInlayHint = async (hint, token) => {
                const dto = hint;
                if (!dto.cacheId) {
                    return hint;
                }
                const result = await this.proxy.$resolveInlayHint(handle, dto.cacheId, token);
                if (token.isCancellationRequested) {
                    throw new ext_types_1.CancellationError();
                }
                if (!result) {
                    return hint;
                }
                return {
                    ...hint,
                    tooltip: result.tooltip,
                    label: (0, ide_core_common_1.revive)(result.label),
                };
            };
        }
        if (typeof eventHandle === 'number') {
            const emitter = new ide_core_common_1.Emitter();
            this.disposables.set(eventHandle, emitter);
            provider.onDidChangeInlayHints = emitter.event;
        }
        this.disposables.set(handle, languages_1.languageFeaturesService.inlayHintsProvider.register(selector, provider));
    }
    $emitInlayHintsEvent(eventHandle, event) {
        const obj = this.disposables.get(eventHandle);
        if (obj instanceof ide_core_common_1.Emitter) {
            obj.fire(event);
        }
    }
    $setLanguageStatus(handle, status) {
        var _a;
        (_a = this._status.get(handle)) === null || _a === void 0 ? void 0 : _a.dispose();
        this._status.set(handle, this.languageStatusService.addStatus(status));
    }
    $removeLanguageStatus(handle) {
        var _a;
        (_a = this._status.get(handle)) === null || _a === void 0 ? void 0 : _a.dispose();
    }
};
exports.MainThreadLanguages = MainThreadLanguages;
tslib_1.__decorate([
    (0, di_1.Autowired)(ide_core_common_1.MarkerManager),
    tslib_1.__metadata("design:type", ide_core_common_1.MarkerManager)
], MainThreadLanguages.prototype, "markerManager", void 0);
tslib_1.__decorate([
    (0, di_1.Autowired)(ide_core_browser_1.PreferenceService),
    tslib_1.__metadata("design:type", Object)
], MainThreadLanguages.prototype, "preference", void 0);
tslib_1.__decorate([
    (0, di_1.Autowired)(ide_core_browser_1.IReporterService),
    tslib_1.__metadata("design:type", Object)
], MainThreadLanguages.prototype, "reporter", void 0);
tslib_1.__decorate([
    (0, di_1.Autowired)(ide_editor_1.ILanguageService),
    tslib_1.__metadata("design:type", Object)
], MainThreadLanguages.prototype, "languageService", void 0);
tslib_1.__decorate([
    (0, di_1.Autowired)(callHierarchy_1.ICallHierarchyService),
    tslib_1.__metadata("design:type", Object)
], MainThreadLanguages.prototype, "callHierarchyService", void 0);
tslib_1.__decorate([
    (0, di_1.Autowired)(typeHierarchy_1.ITypeHierarchyService),
    tslib_1.__metadata("design:type", Object)
], MainThreadLanguages.prototype, "typeHierarchyService", void 0);
tslib_1.__decorate([
    (0, di_1.Autowired)(evaluatable_expression_1.IEvaluatableExpressionService),
    tslib_1.__metadata("design:type", Object)
], MainThreadLanguages.prototype, "evaluatableExpressionService", void 0);
tslib_1.__decorate([
    (0, di_1.Autowired)(browser_1.IEditorDocumentModelService),
    tslib_1.__metadata("design:type", Object)
], MainThreadLanguages.prototype, "documentModelManager", void 0);
tslib_1.__decorate([
    (0, di_1.Autowired)(browser_1.ILanguageStatusService),
    tslib_1.__metadata("design:type", Object)
], MainThreadLanguages.prototype, "languageStatusService", void 0);
tslib_1.__decorate([
    (0, di_1.Autowired)(tokenizer_1.ITextmateTokenizer),
    tslib_1.__metadata("design:type", Object)
], MainThreadLanguages.prototype, "textmateService", void 0);
exports.MainThreadLanguages = MainThreadLanguages = tslib_1.__decorate([
    (0, di_1.Injectable)({ multiple: true }),
    tslib_1.__param(0, (0, di_1.Optional)(Symbol())),
    tslib_1.__metadata("design:paramtypes", [Object])
], MainThreadLanguages);
//# sourceMappingURL=main.thread.language.js.map