"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ExtHostLanguages = void 0;
exports.createLanguagesApiFactory = createLanguagesApiFactory;
const tslib_1 = require("tslib");
const ide_core_common_1 = require("@opensumi/ide-core-common");
const vscode_1 = require("../../../common/vscode");
const typeConvert = tslib_1.__importStar(require("../../../common/vscode/converter"));
const ext_types_1 = require("../../../common/vscode/ext-types");
const utils_1 = require("../../../common/vscode/utils");
const callhierarchy_1 = require("./language/callhierarchy");
const code_action_1 = require("./language/code-action");
const color_1 = require("./language/color");
const completion_1 = require("./language/completion");
const declaration_1 = require("./language/declaration");
const definition_1 = require("./language/definition");
const diagnostics_1 = require("./language/diagnostics");
const document_highlight_1 = require("./language/document-highlight");
const evaluatableExpression_1 = require("./language/evaluatableExpression");
const folding_1 = require("./language/folding");
const hover_1 = require("./language/hover");
const implementation_1 = require("./language/implementation");
const inlay_hints_1 = require("./language/inlay-hints");
const inline_values_1 = require("./language/inline-values");
const inlineCompletion_1 = require("./language/inlineCompletion");
const inlineEdit_1 = require("./language/inlineEdit");
const lens_1 = require("./language/lens");
const link_provider_1 = require("./language/link-provider");
const linked_editing_range_1 = require("./language/linked-editing-range");
const new_symbol_names_1 = require("./language/new-symbol-names");
const on_type_formatting_1 = require("./language/on-type-formatting");
const outline_1 = require("./language/outline");
const range_formatting_1 = require("./language/range-formatting");
const reference_1 = require("./language/reference");
const rename_1 = require("./language/rename");
const selection_1 = require("./language/selection");
const semantic_tokens_1 = require("./language/semantic-tokens");
const signature_1 = require("./language/signature");
const type_definition_1 = require("./language/type-definition");
const type_hierarchy_1 = require("./language/type-hierarchy");
const util_1 = require("./language/util");
const workspace_symbol_1 = require("./language/workspace-symbol");
function createLanguagesApiFactory(extHostLanguages, extHostNotebook, extension) {
    return {
        getLanguages() {
            return extHostLanguages.getLanguages();
        },
        registerHoverProvider(selector, provider) {
            return extHostLanguages.registerHoverProvider(selector, provider, extension);
        },
        registerCompletionItemProvider(selector, provider, ...triggerCharacters) {
            return extHostLanguages.registerCompletionItemProvider(selector, provider, triggerCharacters, extension);
        },
        registerInlineCompletionItemProvider(selector, provider, metadata) {
            return extHostLanguages.registerInlineCompletionsProvider(extension, selector, provider, metadata);
        },
        registerInlineEditProvider(selector, provider) {
            return extHostLanguages.registerInlineEditProvider(extension, selector, provider);
        },
        registerDefinitionProvider(selector, provider) {
            return extHostLanguages.registerDefinitionProvider(selector, provider, extension);
        },
        registerTypeDefinitionProvider(selector, provider) {
            return extHostLanguages.registerTypeDefinitionProvider(selector, provider, extension);
        },
        registerFoldingRangeProvider(selector, provider) {
            return extHostLanguages.registerFoldingRangeProvider(selector, provider, extension);
        },
        registerColorProvider(selector, provider) {
            return extHostLanguages.registerColorProvider(selector, provider, extension);
        },
        registerDocumentHighlightProvider(selector, provider) {
            return extHostLanguages.registerDocumentHighlightProvider(selector, provider, extension);
        },
        registerDocumentLinkProvider(selector, provider) {
            return extHostLanguages.registerDocumentLinkProvider(selector, provider, extension);
        },
        registerReferenceProvider(selector, provider) {
            return extHostLanguages.registerReferenceProvider(selector, provider, extension);
        },
        match(selector, document) {
            const interalSelector = typeConvert.fromLanguageSelector(selector);
            let notebook;
            if (interalSelector && (0, util_1.targetsNotebooks)(interalSelector)) {
                notebook = extHostNotebook.notebookDocuments.find((value) => value.getCells().find((c) => c.document === document));
            }
            return (0, util_1.score)(interalSelector, document.uri, document.languageId, true, notebook === null || notebook === void 0 ? void 0 : notebook.uri, notebook === null || notebook === void 0 ? void 0 : notebook.notebookType);
        },
        setLanguageConfiguration(language, configuration) {
            return extHostLanguages.setLanguageConfiguration(language, configuration);
        },
        setTextDocumentLanguage(document, languageId) {
            return extHostLanguages.changeLanguage(document.uri, languageId);
        },
        createDiagnosticCollection(name) {
            return extHostLanguages.createDiagnosticCollection(name);
        },
        get onDidChangeDiagnostics() {
            return extHostLanguages.onDidChangeDiagnostics;
        },
        getDiagnostics(resource) {
            return extHostLanguages.getDiagnostics(resource);
        },
        registerWorkspaceSymbolProvider(provider) {
            return extHostLanguages.registerWorkspaceSymbolProvider(provider, extension);
        },
        registerDocumentSymbolProvider(selector, provider) {
            return extHostLanguages.registerDocumentSymbolProvider(selector, provider, extension);
        },
        registerImplementationProvider(selector, provider) {
            return extHostLanguages.registerImplementationProvider(selector, provider, extension);
        },
        registerDeclarationProvider(selector, provider) {
            return extHostLanguages.registerDeclarationProvider(selector, provider, extension);
        },
        registerCodeActionsProvider(selector, provider, metadata) {
            return extHostLanguages.registerCodeActionsProvider(extension, selector, provider, metadata);
        },
        registerRenameProvider(selector, provider) {
            return extHostLanguages.registerRenameProvider(selector, provider, extension);
        },
        registerNewSymbolNamesProvider(selector, provider) {
            return extHostLanguages.registerNewSymbolNamesProvider(selector, provider, extension);
        },
        registerSignatureHelpProvider(selector, provider, firstItem, ...remaining) {
            if (typeof firstItem === 'object') {
                return extHostLanguages.registerSignatureHelpProvider(selector, provider, firstItem, extension);
            }
            return extHostLanguages.registerSignatureHelpProvider(selector, provider, typeof firstItem === 'undefined' ? [] : [firstItem, ...remaining], extension);
        },
        registerCodeLensProvider(selector, provider) {
            return extHostLanguages.registerCodeLensProvider(selector, provider, extension);
        },
        registerOnTypeFormattingEditProvider(selector, provider, firstTriggerCharacter, ...moreTriggerCharacter) {
            return extHostLanguages.registerOnTypeFormattingEditProvider(selector, provider, [firstTriggerCharacter].concat(moreTriggerCharacter), extension);
        },
        registerDocumentRangeFormattingEditProvider(selector, provider) {
            return extHostLanguages.registerDocumentRangeFormattingEditProvider(extension, selector, provider);
        },
        registerDocumentFormattingEditProvider(selector, provider) {
            return extHostLanguages.registerDocumentFormattingEditProvider(extension, selector, provider);
        },
        registerSelectionRangeProvider(selector, provider) {
            return extHostLanguages.registerSelectionRangeProvider(selector, provider, extension);
        },
        registerCallHierarchyProvider(selector, provider) {
            return extHostLanguages.registerCallHierarchyProvider(selector, provider, extension);
        },
        registerTypeHierarchyProvider(selector, provider) {
            return extHostLanguages.registerTypeHierarchyProvider(selector, provider, extension);
        },
        registerDocumentSemanticTokensProvider(selector, provider, legend) {
            return extHostLanguages.registerDocumentSemanticTokensProvider(selector, provider, legend, extension);
        },
        registerDocumentRangeSemanticTokensProvider(selector, provider, legend) {
            return extHostLanguages.registerDocumentRangeSemanticTokensProvider(extension, selector, provider, legend);
        },
        registerEvaluatableExpressionProvider(selector, provider) {
            return extHostLanguages.registerEvaluatableExpressionProvider(extension, selector, provider);
        },
        registerInlineValuesProvider(selector, provider) {
            return extHostLanguages.registerInlineValuesProvider(extension, selector, provider);
        },
        registerLinkedEditingRangeProvider(selector, provider) {
            return extHostLanguages.registerLinkedEditingRangeProvider(extension, selector, provider);
        },
        registerInlayHintsProvider(selector, provider) {
            return extHostLanguages.registerInlayHintsProvider(extension, selector, provider);
        },
        createLanguageStatusItem(id, selector) {
            return extHostLanguages.createLanguageStatusItem(extension, id, selector);
        },
        registerDocumentDropEditProvider(selector, provider, metadata) {
            return extHostLanguages.registerDocumentDropEditProvider(extension, selector, provider, metadata);
        },
        registerDocumentPasteEditProvider(selector, provider, metadata) {
            return extHostLanguages.registerDocumentPasteEditProvider(extension, selector, provider, metadata);
        },
        /**
         * @monaco-todo: wait until API is available in Monaco (1.85.0+)
         */
        // eslint-disable-next-line @typescript-eslint/no-unused-vars
        registerMultiDocumentHighlightProvider(selector, provider) {
            return (0, ide_core_common_1.toDisposable)(() => { });
        },
    };
}
class AdapterData {
    constructor(adapter, extension) {
        this.adapter = adapter;
        this.extension = extension;
    }
}
class ExtHostLanguages {
    constructor(rpcProtocol, documents, commands, logService) {
        this.documents = documents;
        this.commands = commands;
        this.logService = logService;
        this.callId = 0;
        this._adapter = new Map();
        this._handlePool = 0;
        this._ids = new Set();
        this.rpcProtocol = rpcProtocol;
        this.proxy = this.rpcProtocol.getProxy(vscode_1.MainThreadAPIIdentifier.MainThreadLanguages);
        this.diagnostics = new diagnostics_1.Diagnostics(this.proxy);
    }
    $resolveCodeAction(handle, id, token) {
        return this.withAdapter(handle, code_action_1.CodeActionAdapter, (adapter) => adapter.resolveCodeAction(id, token), false, undefined);
    }
    $releaseCodeActions(handle, cacheId) {
        this.withAdapter(handle, code_action_1.CodeActionAdapter, (adapter) => Promise.resolve(adapter.releaseCodeActions(cacheId)), false, undefined);
    }
    nextCallId() {
        return this.callId++;
    }
    createDisposable(callId) {
        return new ext_types_1.Disposable(() => {
            this._adapter.delete(callId);
            this.proxy.$unregister(callId);
        });
    }
    addNewAdapter(adapter, extension) {
        const callId = this.nextCallId();
        this._adapter.set(callId, { adapter, extension });
        return callId;
    }
    static _extLabel(ext) {
        return ext.displayName || ext.name;
    }
    withAdapter(handle, constructor, callback, allowCancellationError = false, fallbackValue) {
        const data = this._adapter.get(handle);
        if (!data || !data.adapter || !(data.adapter instanceof constructor)) {
            return Promise.resolve(fallbackValue);
        }
        const p = callback(data.adapter, data.extension);
        p.catch((err) => {
            const isExpectedError = allowCancellationError && err instanceof ext_types_1.CancellationError;
            if (!isExpectedError) {
                this.logService.error(err);
            }
        });
        return p;
    }
    withDurationRecord(action) {
        const duration = (0, util_1.getDurationTimer)();
        return action().then((result) => ({ _dur: duration.end(), result }));
    }
    transformDocumentSelector(selector) {
        if (Array.isArray(selector)) {
            return selector.map((sel) => this.doTransformDocumentSelector(sel));
        }
        return [this.doTransformDocumentSelector(selector)];
    }
    doTransformDocumentSelector(selector) {
        if (typeof selector === 'string') {
            return {
                $serialized: true,
                language: selector,
            };
        }
        if (selector) {
            return {
                $serialized: true,
                language: selector.language,
                scheme: selector.scheme,
                pattern: selector.pattern,
            };
        }
        return undefined;
    }
    async getLanguages() {
        return this.proxy.$getLanguages();
    }
    async changeLanguage(uri, languageId) {
        await this.proxy.$changeLanguage(uri, languageId);
        const data = this.documents.getDocumentData(uri);
        if (!data) {
            throw new Error(`document '${uri.toString()}' NOT found`);
        }
        return data.document;
    }
    // ### Hover begin
    registerHoverProvider(selector, provider, extension) {
        const callId = this.addNewAdapter(new hover_1.HoverAdapter(provider, this.documents), extension);
        this.proxy.$registerHoverProvider(callId, this.transformDocumentSelector(selector));
        return this.createDisposable(callId);
    }
    $provideHover(handle, resource, position, token) {
        return this.withAdapter(handle, hover_1.HoverAdapter, (adapter) => adapter.provideHover(resource, position, token), false, undefined);
    }
    $provideHoverWithDuration(handle, resource, position, token) {
        return this.withDurationRecord(() => this.$provideHover(handle, resource, position, token));
    }
    // ### Hover end
    // ### Completion begin
    $provideCompletionItems(handle, resource, position, context, token) {
        return this.withAdapter(handle, completion_1.CompletionAdapter, (adapter) => adapter.provideCompletionItems(resource, position, context, token), false, undefined);
    }
    $resolveCompletionItem(handle, id, token) {
        return this.withAdapter(handle, completion_1.CompletionAdapter, (adapter) => adapter.resolveCompletionItem(id, token), false, undefined);
    }
    $releaseCompletionItems(handle, id) {
        this.withAdapter(handle, completion_1.CompletionAdapter, (adapter) => adapter.releaseCompletionItems(id), false, undefined);
    }
    registerCompletionItemProvider(selector, provider, triggerCharacters, extension) {
        const callId = this.addNewAdapter(new completion_1.CompletionAdapter(provider, this.commands.converter, this.documents), extension);
        this.proxy.$registerCompletionSupport(callId, this.transformDocumentSelector(selector), triggerCharacters, completion_1.CompletionAdapter.hasResolveSupport(provider));
        return this.createDisposable(callId);
    }
    registerInlineCompletionsProvider(extension, selector, provider, metadata) {
        var _a;
        const adapter = new inlineCompletion_1.InlineCompletionAdapter(extension, this.documents, provider, this.commands.converter);
        const callId = this.addNewAdapter(adapter, extension);
        this.proxy.$registerInlineCompletionsSupport(callId, this.transformDocumentSelector(selector), true, vscode_1.ExtensionIdentifier.toKey(extension.identifier.value), ((_a = metadata === null || metadata === void 0 ? void 0 : metadata.yieldTo) === null || _a === void 0 ? void 0 : _a.map((extId) => vscode_1.ExtensionIdentifier.toKey(extId))) || []);
        return this.createDisposable(callId);
    }
    registerInlineEditProvider(extension, selector, provider) {
        const adapter = new inlineEdit_1.InlineEditAdapter(extension, this.documents, provider, this.commands.converter);
        const callId = this.addNewAdapter(adapter, extension);
        this.proxy.$registerInlineEditProvider(callId, this.transformDocumentSelector(selector), extension.identifier, provider.displayName || extension.name);
        return this.createDisposable(callId);
    }
    $provideInlineEdit(handle, resource, context, token) {
        return this.withAdapter(handle, inlineEdit_1.InlineEditAdapter, (adapter) => adapter.provideInlineEdits(ide_core_common_1.Uri.revive(resource), context, token), undefined, undefined);
    }
    $freeInlineEdit(handle, pid) {
        this.withAdapter(handle, inlineEdit_1.InlineEditAdapter, async (adapter) => {
            // 增加延迟释放，避免在 ESC 退出时，InlineEdit 的 Rejected 命令被提前销毁导致异常
            setTimeout(() => adapter.disposeEdit(pid), 100);
        }, undefined, undefined);
    }
    $provideInlineCompletions(handle, resource, position, context, token) {
        return this.withAdapter(handle, inlineCompletion_1.InlineCompletionAdapterBase, (adapter) => adapter.provideInlineCompletions(ide_core_common_1.Uri.revive(resource), position, context, token), undefined, undefined);
    }
    $handleInlineCompletionDidShow(handle, pid, idx, updatedInsertText) {
        this.withAdapter(handle, inlineCompletion_1.InlineCompletionAdapterBase, async (adapter) => {
            adapter.handleDidShowCompletionItem(pid, idx, updatedInsertText);
        }, undefined, undefined);
    }
    $handleInlineCompletionPartialAccept(handle, pid, idx, acceptedCharacters) {
        this.withAdapter(handle, inlineCompletion_1.InlineCompletionAdapterBase, async (adapter) => {
            adapter.handlePartialAccept(pid, idx, acceptedCharacters);
        }, undefined, undefined);
    }
    $freeInlineCompletionsList(handle, pid) {
        this.withAdapter(handle, inlineCompletion_1.InlineCompletionAdapterBase, async (adapter) => {
            adapter.disposeCompletions(pid);
        }, undefined, undefined);
    }
    // ### Inline Completion end
    // ### Definition provider begin
    $provideDefinition(handle, resource, position, token) {
        return this.withAdapter(handle, definition_1.DefinitionAdapter, (adapter) => adapter.provideDefinition(resource, position, token), false, undefined);
    }
    $provideDefinitionWithDuration(handle, resource, position, token) {
        return this.withDurationRecord(() => this.$provideDefinition(handle, resource, position, token));
    }
    registerDefinitionProvider(selector, provider, extension) {
        const callId = this.addNewAdapter(new definition_1.DefinitionAdapter(provider, this.documents), extension);
        this.proxy.$registerDefinitionProvider(callId, this.transformDocumentSelector(selector));
        return this.createDisposable(callId);
    }
    // ### Definition provider end
    // ### Type Definition provider begin
    $provideTypeDefinition(handle, resource, position, token) {
        return this.withAdapter(handle, type_definition_1.TypeDefinitionAdapter, (adapter) => adapter.provideTypeDefinition(resource, position, token), false, undefined);
    }
    $provideTypeDefinitionWithDuration(handle, resource, position, token) {
        return this.withDurationRecord(() => this.$provideTypeDefinition(handle, resource, position, token));
    }
    registerTypeDefinitionProvider(selector, provider, extension) {
        const callId = this.addNewAdapter(new type_definition_1.TypeDefinitionAdapter(provider, this.documents), extension);
        this.proxy.$registerTypeDefinitionProvider(callId, this.transformDocumentSelector(selector));
        return this.createDisposable(callId);
    }
    // ### Type Definition provider end
    registerFoldingRangeProvider(selector, provider, extension) {
        const callId = this.addNewAdapter(new folding_1.FoldingProviderAdapter(this.documents, provider), extension);
        const eventHandle = typeof provider.onDidChangeFoldingRanges === 'function' ? this.nextCallId() : undefined;
        this.proxy.$registerFoldingRangeProvider(callId, this.transformDocumentSelector(selector), eventHandle);
        let result = this.createDisposable(callId);
        if (eventHandle !== undefined) {
            const subscription = provider.onDidChangeFoldingRanges(() => this.proxy.$emitFoldingRangeEvent(eventHandle));
            result = ext_types_1.Disposable.from(result, subscription);
        }
        return result;
    }
    $provideFoldingRange(handle, resource, context, token) {
        return this.withAdapter(handle, folding_1.FoldingProviderAdapter, (adapter) => adapter.provideFoldingRanges(resource, context, token), false, undefined);
    }
    // ### Color Provider begin
    registerColorProvider(selector, provider, extension) {
        const callId = this.addNewAdapter(new color_1.ColorProviderAdapter(this.documents, provider), extension);
        this.proxy.$registerDocumentColorProvider(callId, this.transformDocumentSelector(selector));
        return this.createDisposable(callId);
    }
    $provideDocumentColors(handle, resource, token) {
        return this.withAdapter(handle, color_1.ColorProviderAdapter, (adapter) => adapter.provideColors(resource, token), false, []);
    }
    $provideColorPresentations(handle, resource, colorInfo, token) {
        return this.withAdapter(handle, color_1.ColorProviderAdapter, (adapter) => adapter.provideColorPresentations(resource, colorInfo, token), false, []);
    }
    // ### Color Provider end
    // ### Document Highlight Provider begin
    registerDocumentHighlightProvider(selector, provider, extension) {
        const callId = this.addNewAdapter(new document_highlight_1.DocumentHighlightAdapter(provider, this.documents), extension);
        this.proxy.$registerDocumentHighlightProvider(callId, this.transformDocumentSelector(selector));
        return this.createDisposable(callId);
    }
    $provideDocumentHighlights(handle, resource, position, token) {
        return this.withAdapter(handle, document_highlight_1.DocumentHighlightAdapter, (adapter) => adapter.provideDocumentHighlights(resource, position, token), false, undefined);
    }
    // ### Document Highlight Provider end
    // ### Document Formatting Provider begin
    registerDocumentFormattingEditProvider(extension, selector, provider) {
        const callId = this.addNewAdapter(new range_formatting_1.FormattingAdapter(provider, this.documents), extension);
        this.proxy.$registerDocumentFormattingProvider(callId, extension, this.transformDocumentSelector(selector));
        return this.createDisposable(callId);
    }
    $provideDocumentFormattingEdits(handle, resource, options) {
        return this.withAdapter(handle, range_formatting_1.FormattingAdapter, (adapter) => adapter.provideDocumentFormattingEdits(resource, options), false, undefined);
    }
    // ### Document Formatting Provider end
    // ### Document Range Formatting Provider begin
    registerDocumentRangeFormattingEditProvider(extension, selector, provider) {
        const callId = this.addNewAdapter(new range_formatting_1.RangeFormattingAdapter(provider, this.documents), extension);
        this.proxy.$registerRangeFormattingProvider(callId, extension, this.transformDocumentSelector(selector));
        return this.createDisposable(callId);
    }
    $provideDocumentRangeFormattingEdits(handle, resource, range, options) {
        return this.withAdapter(handle, range_formatting_1.RangeFormattingAdapter, (adapter) => adapter.provideDocumentRangeFormattingEdits(resource, range, options), false, undefined);
    }
    // ### Document Range Formatting Provider end
    // ### Document Type Formatting Provider begin
    registerOnTypeFormattingEditProvider(selector, provider, triggerCharacters, extension) {
        const callId = this.addNewAdapter(new on_type_formatting_1.OnTypeFormattingAdapter(provider, this.documents), extension);
        this.proxy.$registerOnTypeFormattingProvider(callId, this.transformDocumentSelector(selector), triggerCharacters);
        return this.createDisposable(callId);
    }
    $provideOnTypeFormattingEdits(handle, resource, position, ch, options) {
        return this.withAdapter(handle, on_type_formatting_1.OnTypeFormattingAdapter, (adapter) => adapter.provideOnTypeFormattingEdits(resource, position, ch, options), false, undefined);
    }
    $provideOnTypeFormattingEditsWithDuration(handle, resource, position, ch, options) {
        return this.withDurationRecord(() => this.$provideOnTypeFormattingEdits(handle, resource, position, ch, options));
    }
    // ### Document Type Formatting Provider end
    // ### Document Code Lens Provider begin
    registerCodeLensProvider(selector, provider, extension) {
        const callId = this.addNewAdapter(new lens_1.CodeLensAdapter(provider, this.documents, this.commands.converter), extension);
        const eventHandle = typeof provider.onDidChangeCodeLenses === 'function' ? this.nextCallId() : undefined;
        this.proxy.$registerCodeLensSupport(callId, this.transformDocumentSelector(selector), eventHandle);
        let result = this.createDisposable(callId);
        if (eventHandle !== undefined && provider.onDidChangeCodeLenses) {
            const subscription = provider.onDidChangeCodeLenses((e) => this.proxy.$emitCodeLensEvent(eventHandle));
            result = ext_types_1.Disposable.from(result, subscription);
        }
        return result;
    }
    $provideCodeLenses(handle, resource, token) {
        return this.withAdapter(handle, lens_1.CodeLensAdapter, (adapter) => adapter.provideCodeLenses(resource, token), false, undefined);
    }
    $resolveCodeLens(handle, symbol, token) {
        return this.withAdapter(handle, lens_1.CodeLensAdapter, (adapter) => adapter.resolveCodeLens(symbol, token), false, undefined);
    }
    $releaseCodeLens(handle, cacheId) {
        return this.withAdapter(handle, lens_1.CodeLensAdapter, (adapter) => Promise.resolve(adapter.releaseCodeLens(cacheId)), false, undefined);
    }
    // ### Document Code Lens Provider end
    // ### Code Actions Provider begin
    registerCodeActionsProvider(extension, selector, provider, metadata) {
        var _a, _b;
        const store = new ide_core_common_1.DisposableStore();
        const callId = this.addNewAdapter(new code_action_1.CodeActionAdapter(provider, this.documents, this.diagnostics), extension);
        this.proxy.$registerQuickFixProvider(callId, this.transformDocumentSelector(selector), {
            providedKinds: (_a = metadata === null || metadata === void 0 ? void 0 : metadata.providedCodeActionKinds) === null || _a === void 0 ? void 0 : _a.map((kind) => kind.value),
            documentation: (_b = metadata === null || metadata === void 0 ? void 0 : metadata.documentation) === null || _b === void 0 ? void 0 : _b.map((doc) => ({
                kind: doc.kind.value,
                command: this.commands.converter.toInternal(doc.command, store),
            })),
        }, extension.displayName || extension.name, Boolean(provider.resolveCodeAction));
        return this.createDisposable(callId);
    }
    $provideCodeActions(handle, resource, rangeOrSelection, context, token) {
        return this.withAdapter(handle, code_action_1.CodeActionAdapter, (adapter) => adapter.provideCodeActions(resource, rangeOrSelection, context, this.commands.converter, token), false, undefined);
    }
    // ### Code Actions Provider end
    // ### Implementation provider begin
    $provideImplementation(handle, resource, position) {
        return this.withAdapter(handle, implementation_1.ImplementationAdapter, (adapter) => adapter.provideImplementation(resource, position), false, undefined);
    }
    $provideImplementationWithDuration(handle, resource, position) {
        return this.withDurationRecord(() => this.$provideImplementation(handle, resource, position));
    }
    registerImplementationProvider(selector, provider, extension) {
        const callId = this.addNewAdapter(new implementation_1.ImplementationAdapter(provider, this.documents), extension);
        this.proxy.$registerImplementationProvider(callId, this.transformDocumentSelector(selector));
        return this.createDisposable(callId);
    }
    // ### Implementation provider end
    // ### Declaration provider begin
    registerDeclarationProvider(selector, provider, extension) {
        const callId = this.addNewAdapter(new declaration_1.DeclarationAdapter(provider, this.documents), extension);
        this.proxy.$registerDeclarationProvider(callId, this.transformDocumentSelector(selector));
        return this.createDisposable(callId);
    }
    // ### Declaration provider end
    // ### Diagnostics begin
    get onDidChangeDiagnostics() {
        return this.diagnostics.onDidChangeDiagnostics;
    }
    getDiagnostics(resource) {
        return this.diagnostics.getDiagnostics(resource);
    }
    createDiagnosticCollection(name) {
        return this.diagnostics.createDiagnosticCollection(name);
    }
    // ### Diagnostics end
    // ### Document Link Provider begin
    $provideDocumentLinks(handle, resource, token) {
        return this.withAdapter(handle, link_provider_1.LinkProviderAdapter, (adapter) => adapter.provideLinks(resource, token), false, undefined);
    }
    $resolveDocumentLink(handle, id, token) {
        return this.withAdapter(handle, link_provider_1.LinkProviderAdapter, (adapter) => adapter.resolveLink(id, token), false, undefined);
    }
    $releaseDocumentLinks(handle, cacheId) {
        return this.withAdapter(handle, link_provider_1.LinkProviderAdapter, (adapter) => Promise.resolve(adapter.releaseLink(cacheId)), false, undefined);
    }
    registerDocumentLinkProvider(selector, provider, extension) {
        const callId = this.addNewAdapter(new link_provider_1.LinkProviderAdapter(provider, this.documents), extension);
        this.proxy.$registerDocumentLinkProvider(callId, this.transformDocumentSelector(selector), typeof provider.resolveDocumentLink === 'function');
        return this.createDisposable(callId);
    }
    // ### Document Link Provider end
    // ### Code Reference Provider begin
    $provideReferences(handle, resource, position, context, token) {
        return this.withAdapter(handle, reference_1.ReferenceAdapter, (adapter) => adapter.provideReferences(resource, position, context, token), false, undefined);
    }
    $provideReferencesWithDuration(handle, resource, position, context, token) {
        return this.withDurationRecord(() => this.$provideReferences(handle, resource, position, context, token));
    }
    registerReferenceProvider(selector, provider, extension) {
        const callId = this.addNewAdapter(new reference_1.ReferenceAdapter(provider, this.documents), extension);
        this.proxy.$registerReferenceProvider(callId, this.transformDocumentSelector(selector));
        return this.createDisposable(callId);
    }
    // ### Code Reference Provider end
    setLanguageConfiguration(language, configuration) {
        const { wordPattern } = configuration;
        if (wordPattern) {
            this.documents.setWordDefinitionFor(language, wordPattern);
        }
        else {
            this.documents.setWordDefinitionFor(language, undefined);
        }
        const callId = this.nextCallId();
        const config = {
            brackets: configuration.brackets,
            comments: configuration.comments,
            onEnterRules: (0, utils_1.serializeEnterRules)(configuration.onEnterRules),
            wordPattern: (0, utils_1.serializeRegExp)(configuration.wordPattern),
            indentationRules: (0, utils_1.serializeIndentation)(configuration.indentationRules),
            autoClosingPairs: (0, utils_1.serializeAutoClosingPairs)(configuration.autoClosingPairs),
        };
        this.proxy.$setLanguageConfiguration(callId, language, config);
        return this.createDisposable(callId);
    }
    // ### Document Symbol Provider begin
    registerDocumentSymbolProvider(selector, provider, extension) {
        const callId = this.addNewAdapter(new outline_1.OutlineAdapter(this.documents, provider), extension);
        this.proxy.$registerOutlineSupport(callId, this.transformDocumentSelector(selector));
        return this.createDisposable(callId);
    }
    $provideDocumentSymbols(handle, resource, token) {
        return this.withAdapter(handle, outline_1.OutlineAdapter, (adapter) => adapter.provideDocumentSymbols(resource, token), false, undefined);
    }
    // ### Document Symbol Provider end
    // ### WorkspaceSymbol Provider begin
    registerWorkspaceSymbolProvider(provider, extension) {
        const callId = this.addNewAdapter(new workspace_symbol_1.WorkspaceSymbolAdapter(provider), extension);
        this.proxy.$registerWorkspaceSymbolProvider(callId);
        return this.createDisposable(callId);
    }
    $provideWorkspaceSymbols(handle, query, token) {
        return this.withAdapter(handle, workspace_symbol_1.WorkspaceSymbolAdapter, (adapter) => adapter.provideWorkspaceSymbols(query, token), false, []);
    }
    $resolveWorkspaceSymbol(handle, symbol, token) {
        return this.withAdapter(handle, workspace_symbol_1.WorkspaceSymbolAdapter, (adapter) => adapter.resolveWorkspaceSymbol(symbol, token), false, undefined);
    }
    // ### WorkspaceSymbol Provider end
    // ### Signature help begin
    $provideSignatureHelp(handle, resource, position, context, token) {
        return this.withAdapter(handle, signature_1.SignatureHelpAdapter, (adapter) => adapter.provideSignatureHelp(resource, position, token, context), false, undefined);
    }
    $releaseSignatureHelp(handle, cacheId) {
        return this.withAdapter(handle, signature_1.SignatureHelpAdapter, (adapter) => Promise.resolve(adapter.releaseSignatureHelp(cacheId)), false, undefined);
    }
    registerSignatureHelpProvider(selector, provider, metadataOrTriggerChars, extension) {
        const metadata = Array.isArray(metadataOrTriggerChars)
            ? { triggerCharacters: metadataOrTriggerChars, retriggerCharacters: [] }
            : metadataOrTriggerChars;
        const callId = this.addNewAdapter(new signature_1.SignatureHelpAdapter(provider, this.documents), extension);
        this.proxy.$registerSignatureHelpProvider(callId, this.transformDocumentSelector(selector), metadata);
        return this.createDisposable(callId);
    }
    // ### Signature help end
    // ### Rename Provider begin
    registerRenameProvider(selector, provider, extension) {
        const callId = this.addNewAdapter(new rename_1.RenameAdapter(provider, this.documents), extension);
        this.proxy.$registerRenameProvider(callId, this.transformDocumentSelector(selector), rename_1.RenameAdapter.supportsResolving(provider));
        return this.createDisposable(callId);
    }
    $provideRenameEdits(handle, resource, position, newName, token) {
        return this.withAdapter(handle, rename_1.RenameAdapter, (adapter) => adapter.provideRenameEdits(resource, position, newName, token), false, undefined);
    }
    $resolveRenameLocation(handle, resource, position, token) {
        return this.withAdapter(handle, rename_1.RenameAdapter, (adapter) => adapter.resolveRenameLocation(resource, position, token), false, undefined);
    }
    // ### Rename Provider end
    // ### New Symbol Names Provider start
    registerNewSymbolNamesProvider(selector, provider, extension) {
        const callId = this.addNewAdapter(new new_symbol_names_1.NewSymbolNamesAdapter(provider, this.documents), extension);
        this.proxy.$registerNewSymbolNamesProvider(callId, this.transformDocumentSelector(selector));
        return this.createDisposable(callId);
    }
    $provideNewSymbolNames(handle, resource, range, triggerKind, token) {
        return this.withAdapter(handle, new_symbol_names_1.NewSymbolNamesAdapter, (adapter) => adapter.provideNewSymbolNames(resource, range, triggerKind, token), false, undefined);
    }
    // ### New Symbol Names Provider end
    // ### smart select
    registerSelectionRangeProvider(selector, provider, extension) {
        const callId = this.addNewAdapter(new selection_1.SelectionRangeAdapter(this.documents, provider), extension);
        this.proxy.$registerSelectionRangeProvider(callId, this.transformDocumentSelector(selector));
        return this.createDisposable(callId);
    }
    $provideSelectionRanges(handle, resource, positions, token) {
        return this.withAdapter(handle, selection_1.SelectionRangeAdapter, (adapter) => adapter.provideSelectionRanges(resource, positions, token), false, []);
    }
    registerCallHierarchyProvider(selector, provider, extension) {
        const callId = this.addNewAdapter(new callhierarchy_1.CallHierarchyAdapter(this.documents, provider), extension);
        this.proxy.$registerCallHierarchyProvider(callId, this.transformDocumentSelector(selector));
        return this.createDisposable(callId);
    }
    $prepareCallHierarchy(handle, resource, position, token) {
        return this.withAdapter(handle, callhierarchy_1.CallHierarchyAdapter, (adapter) => Promise.resolve(adapter.prepareSession(ide_core_common_1.Uri.revive(resource), position, token)), false, undefined);
    }
    $provideCallHierarchyIncomingCalls(handle, sessionId, itemId, token) {
        return this.withAdapter(handle, callhierarchy_1.CallHierarchyAdapter, (adapter) => adapter.provideCallsTo(sessionId, itemId, token), false, undefined);
    }
    $provideCallHierarchyOutgoingCalls(handle, sessionId, itemId, token) {
        return this.withAdapter(handle, callhierarchy_1.CallHierarchyAdapter, (adapter) => adapter.provideCallsFrom(sessionId, itemId, token), false, undefined);
    }
    $releaseCallHierarchy(handle, sessionId) {
        this.withAdapter(handle, callhierarchy_1.CallHierarchyAdapter, (adapter) => Promise.resolve(adapter.releaseSession(sessionId)), false, undefined);
    }
    registerTypeHierarchyProvider(selector, provider, extension) {
        const callId = this.addNewAdapter(new type_hierarchy_1.TypeHierarchyAdapter(this.documents, provider), extension);
        this.proxy.$registerTypeHierarchyProvider(callId, this.transformDocumentSelector(selector));
        return this.createDisposable(callId);
    }
    $prepareTypeHierarchy(handle, resource, position, token) {
        return this.withAdapter(handle, type_hierarchy_1.TypeHierarchyAdapter, (adapter) => Promise.resolve(adapter.prepareSession(ide_core_common_1.Uri.revive(resource), position, token)), false, undefined);
    }
    $provideTypeHierarchySupertypes(handle, sessionId, itemId, token) {
        return this.withAdapter(handle, type_hierarchy_1.TypeHierarchyAdapter, (adapter) => adapter.provideSupertypes(sessionId, itemId, token), false, undefined);
    }
    $provideTypeHierarchySubtypes(handle, sessionId, itemId, token) {
        return this.withAdapter(handle, type_hierarchy_1.TypeHierarchyAdapter, (adapter) => adapter.provideSubtypes(sessionId, itemId, token), false, undefined);
    }
    $releaseTypeHierarchy(handle, sessionId) {
        this.withAdapter(handle, type_hierarchy_1.TypeHierarchyAdapter, (adapter) => Promise.resolve(adapter.releaseSession(sessionId)), false, undefined);
    }
    // #region Semantic Tokens
    registerDocumentSemanticTokensProvider(selector, provider, legend, extension) {
        const callId = this.addNewAdapter(new semantic_tokens_1.DocumentSemanticTokensAdapter(this.documents, provider), extension);
        this.proxy.$registerDocumentSemanticTokensProvider(callId, this.transformDocumentSelector(selector), legend);
        return this.createDisposable(callId);
    }
    $provideDocumentSemanticTokens(handle, resource, previousResultId, token) {
        return this.withAdapter(handle, semantic_tokens_1.DocumentSemanticTokensAdapter, (adapter) => adapter.provideDocumentSemanticTokens(ide_core_common_1.Uri.revive(resource), previousResultId, token), true, null);
    }
    $releaseDocumentSemanticTokens(handle, semanticColoringResultId) {
        this.withAdapter(handle, semantic_tokens_1.DocumentSemanticTokensAdapter, (adapter) => adapter.releaseDocumentSemanticColoring(semanticColoringResultId), false, undefined);
    }
    registerDocumentRangeSemanticTokensProvider(extension, selector, provider, legend) {
        const callId = this.addNewAdapter(new semantic_tokens_1.DocumentRangeSemanticTokensAdapter(this.documents, provider), extension);
        this.proxy.$registerDocumentRangeSemanticTokensProvider(callId, this.transformDocumentSelector(selector), legend);
        return this.createDisposable(callId);
    }
    $provideDocumentRangeSemanticTokens(handle, resource, range, token) {
        return this.withAdapter(handle, semantic_tokens_1.DocumentRangeSemanticTokensAdapter, (adapter) => adapter.provideDocumentRangeSemanticTokens(ide_core_common_1.Uri.revive(resource), range, token), false, null);
    }
    // #endregion
    // #region EvaluatableExpression
    registerEvaluatableExpressionProvider(extension, selector, provider) {
        const callId = this.addNewAdapter(new evaluatableExpression_1.EvaluatableExpressionAdapter(this.documents, provider), extension);
        this.proxy.$registerEvaluatableExpressionProvider(callId, this.transformDocumentSelector(selector));
        return this.createDisposable(callId);
    }
    $provideEvaluatableExpression(handle, resource, position, token) {
        return this.withAdapter(handle, evaluatableExpression_1.EvaluatableExpressionAdapter, (adapter) => adapter.provideEvaluatableExpression(ide_core_common_1.Uri.revive(resource), position, token), false, undefined);
    }
    // #endregion EvaluatableExpression
    // #region Inline Values
    registerInlineValuesProvider(extension, selector, provider) {
        const eventHandle = typeof provider.onDidChangeInlineValues === 'function' ? this.nextCallId() : undefined;
        const handle = this.addNewAdapter(new inline_values_1.InlineValuesAdapter(this.documents, provider), extension);
        this.proxy.$registerInlineValuesProvider(handle, this.transformDocumentSelector(selector), eventHandle);
        let result = this.createDisposable(handle);
        if (eventHandle !== undefined) {
            const subscription = provider.onDidChangeInlineValues((_) => this.proxy.$emitInlineValuesEvent(eventHandle));
            result = ext_types_1.Disposable.from(result, subscription);
        }
        return result;
    }
    $provideInlineValues(handle, resource, range, context, token) {
        return this.withAdapter(handle, inline_values_1.InlineValuesAdapter, (adapter) => adapter.provideInlineValues(ide_core_common_1.Uri.revive(resource), range, context, token), false, undefined);
    }
    // #endregion Inline Values
    // #region Linked Editing
    registerLinkedEditingRangeProvider(extension, selector, provider) {
        const handle = this.addNewAdapter(new linked_editing_range_1.LinkedEditingRangeAdapter(this.documents, provider), extension);
        this.proxy.$registerLinkedEditingRangeProvider(handle, this.transformDocumentSelector(selector));
        return this.createDisposable(handle);
    }
    $provideLinkedEditingRanges(handle, resource, position, token) {
        return this.withAdapter(handle, linked_editing_range_1.LinkedEditingRangeAdapter, async (adapter) => {
            const res = await adapter.provideLinkedEditingRanges(ide_core_common_1.Uri.revive(resource), position, token);
            if (res) {
                return {
                    ranges: res.ranges,
                    wordPattern: res.wordPattern ? (0, utils_1.serializeRegExp)(res.wordPattern) : undefined,
                };
            }
            return undefined;
        }, false, undefined);
    }
    // #endregion Linked Editing
    // --- inline hints
    registerInlayHintsProvider(extension, selector, provider) {
        const eventHandle = typeof provider.onDidChangeInlayHints === 'function' ? this.nextCallId() : undefined;
        const handle = this.addNewAdapter(new inlay_hints_1.InlayHintsAdapter(this.documents, provider, this.commands.converter), extension);
        this.proxy.$registerInlayHintsProvider(handle, this.transformDocumentSelector(selector), typeof provider.resolveInlayHint === 'function', eventHandle, ExtHostLanguages._extLabel(extension));
        let result = this.createDisposable(handle);
        if (eventHandle !== undefined) {
            const subscription = provider.onDidChangeInlayHints(() => this.proxy.$emitInlayHintsEvent(eventHandle));
            result = ext_types_1.Disposable.from(result, subscription);
        }
        return result;
    }
    $provideInlayHints(handle, resource, range, token) {
        return this.withAdapter(handle, inlay_hints_1.InlayHintsAdapter, (adapter) => adapter.provideInlayHints(ide_core_common_1.Uri.revive(resource), range, token), false, undefined);
    }
    $resolveInlayHint(handle, id, token) {
        return this.withAdapter(handle, inlay_hints_1.InlayHintsAdapter, (adapter) => adapter.resolveInlayHint(id, token), true, undefined);
    }
    $releaseInlayHints(handle, id) {
        this.withAdapter(handle, inlay_hints_1.InlayHintsAdapter, (adapter) => adapter.releaseHints(id), false, undefined);
    }
    createLanguageStatusItem(extension, id, selector) {
        var _a;
        const handle = this._handlePool++;
        const proxy = this.proxy;
        const ids = this._ids;
        // enforce extension unique identifier
        const fullyQualifiedId = `${extension.identifier.value}/${id}`;
        if (ids.has(fullyQualifiedId)) {
            throw new Error(`LanguageStatusItem with id '${id}' ALREADY exists`);
        }
        ids.add(fullyQualifiedId);
        const data = {
            selector,
            id,
            name: (_a = extension.displayName) !== null && _a !== void 0 ? _a : extension.name,
            severity: ext_types_1.LanguageStatusSeverity.Information,
            command: undefined,
            text: '',
            detail: '',
            busy: false,
        };
        let soonHandle;
        const commandDisposables = new ide_core_common_1.DisposableStore();
        const updateAsync = () => {
            soonHandle === null || soonHandle === void 0 ? void 0 : soonHandle.dispose();
            soonHandle = (0, ide_core_common_1.disposableTimeout)(() => {
                var _a, _b, _c, _d;
                commandDisposables.clear();
                this.proxy.$setLanguageStatus(handle, {
                    id: fullyQualifiedId,
                    name: (_b = (_a = data.name) !== null && _a !== void 0 ? _a : extension.displayName) !== null && _b !== void 0 ? _b : extension.name,
                    source: (_c = extension.displayName) !== null && _c !== void 0 ? _c : extension.name,
                    // TODO：缺少 uriTransformer，先不传递
                    // selector: typeConvert.DocumentSelector.from(data.selector, this._uriTransformer),
                    selector: typeConvert.DocumentSelector.from(data.selector),
                    label: data.text,
                    detail: (_d = data.detail) !== null && _d !== void 0 ? _d : '',
                    severity: data.severity === ext_types_1.LanguageStatusSeverity.Error
                        ? ide_core_common_1.Severity.Error
                        : data.severity === ext_types_1.LanguageStatusSeverity.Warning
                            ? ide_core_common_1.Severity.Warning
                            : ide_core_common_1.Severity.Info,
                    command: data.command && this.commands.converter.toInternal(data.command, commandDisposables),
                    accessibilityInfo: data.accessibilityInformation,
                    busy: data.busy,
                });
            }, 0);
        };
        const result = {
            dispose() {
                commandDisposables.dispose();
                soonHandle === null || soonHandle === void 0 ? void 0 : soonHandle.dispose();
                proxy.$removeLanguageStatus(handle);
                ids.delete(fullyQualifiedId);
            },
            get id() {
                return data.id;
            },
            get name() {
                return data.name;
            },
            set name(value) {
                data.name = value;
                updateAsync();
            },
            get selector() {
                return data.selector;
            },
            set selector(value) {
                data.selector = value;
                updateAsync();
            },
            get text() {
                return data.text;
            },
            set text(value) {
                data.text = value;
                updateAsync();
            },
            get detail() {
                return data.detail;
            },
            set detail(value) {
                data.detail = value;
                updateAsync();
            },
            get severity() {
                return data.severity;
            },
            set severity(value) {
                data.severity = value;
                updateAsync();
            },
            get accessibilityInformation() {
                return data.accessibilityInformation;
            },
            set accessibilityInformation(value) {
                data.accessibilityInformation = value;
                updateAsync();
            },
            get command() {
                return data.command;
            },
            set command(value) {
                data.command = value;
                updateAsync();
            },
            get busy() {
                return data.busy;
            },
            set busy(value) {
                data.busy = value;
                updateAsync();
            },
        };
        updateAsync();
        return result;
    }
    registerDocumentDropEditProvider(
    // eslint-disable-next-line @typescript-eslint/no-unused-vars
    extension, 
    // eslint-disable-next-line @typescript-eslint/no-unused-vars
    selector, 
    // eslint-disable-next-line @typescript-eslint/no-unused-vars
    provider, 
    // eslint-disable-next-line @typescript-eslint/no-unused-vars
    metadata) {
        return (0, ide_core_common_1.toDisposable)(() => { });
    }
    registerDocumentPasteEditProvider(
    // eslint-disable-next-line @typescript-eslint/no-unused-vars
    extension, 
    // eslint-disable-next-line @typescript-eslint/no-unused-vars
    selector, 
    // eslint-disable-next-line @typescript-eslint/no-unused-vars
    provider, 
    // eslint-disable-next-line @typescript-eslint/no-unused-vars
    metadata) {
        return (0, ide_core_common_1.toDisposable)(() => { });
    }
}
exports.ExtHostLanguages = ExtHostLanguages;
//# sourceMappingURL=ext.host.language.js.map