"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.InlineCompletionAdapter = exports.InlineCompletionAdapterBase = void 0;
const tslib_1 = require("tslib");
const ide_core_common_1 = require("@opensumi/ide-core-common");
const typeConvert = tslib_1.__importStar(require("../../../../common/vscode/converter"));
const ext_types_1 = require("../../../../common/vscode/ext-types");
const languages = tslib_1.__importStar(require("../../../../common/vscode/languages"));
class ReferenceMap {
    constructor() {
        this._references = new Map();
        this._idPool = 1;
    }
    createReferenceId(value) {
        const id = this._idPool++;
        this._references.set(id, value);
        return id;
    }
    disposeReferenceId(referenceId) {
        const value = this._references.get(referenceId);
        this._references.delete(referenceId);
        return value;
    }
    get(referenceId) {
        return this._references.get(referenceId);
    }
}
class InlineCompletionAdapterBase {
    async provideInlineCompletions(resource, position, context, token) {
        return undefined;
    }
    disposeCompletions(pid) { }
    handleDidShowCompletionItem(pid, idx, updatedInsertText) { }
    handlePartialAccept(pid, idx, acceptedCharacters) { }
}
exports.InlineCompletionAdapterBase = InlineCompletionAdapterBase;
class InlineCompletionAdapter extends InlineCompletionAdapterBase {
    constructor(_extension, _documents, _provider, _commands) {
        super();
        this._extension = _extension;
        this._documents = _documents;
        this._provider = _provider;
        this._commands = _commands;
        this._references = new ReferenceMap();
        this.languageTriggerKindToVSCodeTriggerKind = {
            [languages.InlineCompletionTriggerKind.Automatic]: ext_types_1.InlineCompletionTriggerKind.Automatic,
            [languages.InlineCompletionTriggerKind.Explicit]: ext_types_1.InlineCompletionTriggerKind.Invoke,
        };
    }
    async provideInlineCompletions(resource, position, context, token) {
        const doc = this._documents.getDocument(resource);
        const pos = typeConvert.Position.to(position);
        const result = await this._provider.provideInlineCompletionItems(doc, pos, {
            selectedCompletionInfo: context.selectedSuggestionInfo
                ? {
                    range: typeConvert.Range.to(context.selectedSuggestionInfo.range),
                    text: context.selectedSuggestionInfo.text,
                }
                : undefined,
            triggerKind: this.languageTriggerKindToVSCodeTriggerKind[context.triggerKind],
        }, token);
        if (!result) {
            // undefined and null are valid results
            return undefined;
        }
        if (token.isCancellationRequested) {
            // cancelled -> return without further ado, esp no caching
            // of results as they will leak
            return undefined;
        }
        const normalizedResult = Array.isArray(result) ? result : result.items;
        const commands = Array.isArray(result) ? [] : result.commands || [];
        const enableForwardStability = !Array.isArray(result) ? result.enableForwardStability : undefined;
        let disposableStore;
        const pid = this._references.createReferenceId({
            dispose() {
                disposableStore === null || disposableStore === void 0 ? void 0 : disposableStore.dispose();
            },
            items: normalizedResult,
        });
        return {
            pid,
            items: normalizedResult.map((item, idx) => {
                let command;
                if (item.command) {
                    if (!disposableStore) {
                        disposableStore = new ide_core_common_1.DisposableStore();
                    }
                    command = this._commands.toInternal(item.command, disposableStore);
                }
                const insertText = item.insertText;
                return {
                    insertText: typeof insertText === 'string' ? insertText : { snippet: insertText.value },
                    filterText: item.filterText,
                    range: item.range ? typeConvert.Range.from(item.range) : undefined,
                    command,
                    idx,
                    completeBracketPairs: item.completeBracketPairs,
                };
            }),
            commands: commands.map((c) => {
                if (!disposableStore) {
                    disposableStore = new ide_core_common_1.DisposableStore();
                }
                return this._commands.toInternal(c, disposableStore);
            }),
            suppressSuggestions: false,
            enableForwardStability,
        };
    }
    disposeCompletions(pid) {
        const data = this._references.disposeReferenceId(pid);
        data === null || data === void 0 ? void 0 : data.dispose();
    }
    handleDidShowCompletionItem(pid, idx, updatedInsertText) {
        var _a;
        const completionItem = (_a = this._references.get(pid)) === null || _a === void 0 ? void 0 : _a.items[idx];
        if (completionItem) {
            if (this._provider.handleDidShowCompletionItem) {
                this._provider.handleDidShowCompletionItem(completionItem, updatedInsertText);
            }
        }
    }
    handlePartialAccept(pid, idx, acceptedCharacters) {
        var _a;
        const completionItem = (_a = this._references.get(pid)) === null || _a === void 0 ? void 0 : _a.items[idx];
        if (completionItem) {
            if (this._provider.handleDidPartiallyAcceptCompletionItem) {
                this._provider.handleDidPartiallyAcceptCompletionItem(completionItem, acceptedCharacters);
            }
        }
    }
}
exports.InlineCompletionAdapter = InlineCompletionAdapter;
//# sourceMappingURL=inlineCompletion.js.map