import { alert } from '../../../../base/browser/ui/aria/aria.js';
import { raceCancellation, createCancelablePromise } from '../../../../base/common/async.js';
import { KeyCode, KeyMod as KeyMod$1, KeyChord } from '../../../../base/common/keyCodes.js';
import { assertType } from '../../../../base/common/types.js';
import { URI } from '../../../../base/common/uri.js';
import { EditorStateCancellationTokenSource, CodeEditorStateFlag } from '../../editorState/browser/editorState.js';
import { isCodeEditor } from '../../../browser/editorBrowser.js';
import { EditorAction2 } from '../../../browser/editorExtensions.js';
import { ICodeEditorService } from '../../../browser/services/codeEditorService.js';
import { EmbeddedCodeEditorWidget } from '../../../browser/widget/codeEditor/embeddedCodeEditorWidget.js';
import { EditorOption } from '../../../common/config/editorOptions.js';
import { Position } from '../../../common/core/position.js';
import { Range } from '../../../common/core/range.js';
import { ScrollType } from '../../../common/editorCommon.js';
import { EditorContextKeys } from '../../../common/editorContextKeys.js';
import { isLocationLink } from '../../../common/languages.js';
import { ReferencesController } from './peek/referencesController.js';
import { ReferencesModel } from './referencesModel.js';
import { ISymbolNavigationService } from './symbolNavigation.js';
import { MessageController } from '../../message/browser/messageController.js';
import { PeekContext } from '../../peekView/browser/peekView.js';
import { localizeWithPath, localize2WithPath } from '../../../../nls.js';
import { MenuRegistry, MenuId, registerAction2 } from '../../../../platform/actions/common/actions.js';
import { CommandsRegistry } from '../../../../platform/commands/common/commands.js';
import { ICommandService } from '../../../../platform/commands/common/commands.service.js';
import { ContextKeyExpr } from '../../../../platform/contextkey/common/contextkey.js';
import { TextEditorSelectionRevealType, TextEditorSelectionSource } from '../../../../platform/editor/common/editor.js';
import { IInstantiationService } from '../../../../platform/instantiation/common/instantiation.js';
import { KeybindingWeight } from '../../../../platform/keybinding/common/keybindingsRegistry.js';
import { INotificationService } from '../../../../platform/notification/common/notification.service.js';
import { IEditorProgressService } from '../../../../platform/progress/common/progress.service.js';
import { getDefinitionsAtPosition, getDeclarationsAtPosition, getTypeDefinitionsAtPosition, getImplementationsAtPosition, getReferencesAtPosition } from './goToSymbol.js';
import { ILanguageFeaturesService } from '../../../common/services/languageFeatures.js';
import { Iterable } from '../../../../base/common/iterator.js';
import { IsWebContext } from '../../../../platform/contextkey/common/contextkeys.js';
const _moduleId = "vs/editor/contrib/gotoSymbol/browser/goToCommands";
MenuRegistry.appendMenuItem(MenuId.EditorContext, {
    submenu: MenuId.EditorContextPeek,
    title: ( localizeWithPath(_moduleId, 0, "Peek")),
    group: 'navigation',
    order: 100
});
class SymbolNavigationAnchor {
    static is(thing) {
        if (!thing || typeof thing !== 'object') {
            return false;
        }
        if (thing instanceof SymbolNavigationAnchor) {
            return true;
        }
        if (Position.isIPosition(thing.position) && thing.model) {
            return true;
        }
        return false;
    }
    constructor(model, position) {
        this.model = model;
        this.position = position;
    }
}
class SymbolNavigationAction extends EditorAction2 {
    static { this._allSymbolNavigationCommands = ( (new Map())); }
    static { this._activeAlternativeCommands = ( (new Set())); }
    static all() {
        return (
             (SymbolNavigationAction._allSymbolNavigationCommands.values())
        );
    }
    static _patchConfig(opts) {
        const result = { ...opts, f1: true };
        if (result.menu) {
            for (const item of Iterable.wrap(result.menu)) {
                if (item.id === MenuId.EditorContext || item.id === MenuId.EditorContextPeek) {
                    item.when = ( (ContextKeyExpr.and(opts.precondition, item.when)));
                }
            }
        }
        return result;
    }
    constructor(configuration, opts) {
        super(SymbolNavigationAction._patchConfig(opts));
        this.configuration = configuration;
        SymbolNavigationAction._allSymbolNavigationCommands.set(opts.id, this);
    }
    runEditorCommand(accessor, editor, arg, range) {
        if (!editor.hasModel()) {
            return Promise.resolve(undefined);
        }
        const notificationService = accessor.get(INotificationService);
        const editorService = accessor.get(ICodeEditorService);
        const progressService = accessor.get(IEditorProgressService);
        const symbolNavService = accessor.get(ISymbolNavigationService);
        const languageFeaturesService = accessor.get(ILanguageFeaturesService);
        const instaService = accessor.get(IInstantiationService);
        const model = editor.getModel();
        const position = editor.getPosition();
        const anchor = SymbolNavigationAnchor.is(arg) ? arg : ( (new SymbolNavigationAnchor(model, position)));
        const cts = ( (new EditorStateCancellationTokenSource(editor, CodeEditorStateFlag.Value | CodeEditorStateFlag.Position)));
        const promise = raceCancellation(this._getLocationModel(languageFeaturesService, anchor.model, anchor.position, cts.token), cts.token).then(async (references) => {
            if (!references || cts.token.isCancellationRequested) {
                return;
            }
            alert(references.ariaMessage);
            let altAction;
            if (references.referenceAt(model.uri, position)) {
                const altActionId = this._getAlternativeCommand(editor);
                if (!( (SymbolNavigationAction._activeAlternativeCommands.has(altActionId))) && ( (SymbolNavigationAction._allSymbolNavigationCommands.has(altActionId)))) {
                    altAction = SymbolNavigationAction._allSymbolNavigationCommands.get(altActionId);
                }
            }
            const referenceCount = references.references.length;
            if (referenceCount === 0) {
                if (!this.configuration.muteMessage) {
                    const info = model.getWordAtPosition(position);
                    MessageController.get(editor)?.showMessage(this._getNoResultFoundMessage(info), position);
                }
            }
            else if (referenceCount === 1 && altAction) {
                SymbolNavigationAction._activeAlternativeCommands.add(this.desc.id);
                instaService.invokeFunction((accessor) => altAction.runEditorCommand(accessor, editor, arg, range).finally(() => {
                    SymbolNavigationAction._activeAlternativeCommands.delete(this.desc.id);
                }));
            }
            else {
                return this._onResult(editorService, symbolNavService, editor, references, range);
            }
        }, (err) => {
            notificationService.error(err);
        }).finally(() => {
            cts.dispose();
        });
        progressService.showWhile(promise, 250);
        return promise;
    }
    async _onResult(editorService, symbolNavService, editor, model, range) {
        const gotoLocation = this._getGoToPreference(editor);
        if (!(editor instanceof EmbeddedCodeEditorWidget) && (this.configuration.openInPeek || (gotoLocation === 'peek' && model.references.length > 1))) {
            this._openInPeek(editor, model, range);
        }
        else {
            const next = model.firstReference();
            const peek = model.references.length > 1 && gotoLocation === 'gotoAndPeek';
            const targetEditor = await this._openReference(editor, editorService, next, this.configuration.openToSide, !peek);
            if (peek && targetEditor) {
                this._openInPeek(targetEditor, model, range);
            }
            else {
                model.dispose();
            }
            if (gotoLocation === 'goto') {
                symbolNavService.put(next);
            }
        }
    }
    async _openReference(editor, editorService, reference, sideBySide, highlight) {
        let range = undefined;
        if (isLocationLink(reference)) {
            range = reference.targetSelectionRange;
        }
        if (!range) {
            range = reference.range;
        }
        if (!range) {
            return undefined;
        }
        const targetEditor = await editorService.openCodeEditor({
            resource: reference.uri,
            options: {
                selection: Range.collapseToStart(range),
                selectionRevealType: TextEditorSelectionRevealType.NearTopIfOutsideViewport,
                selectionSource: TextEditorSelectionSource.JUMP
            }
        }, editor, sideBySide);
        if (!targetEditor) {
            return undefined;
        }
        if (highlight) {
            const modelNow = targetEditor.getModel();
            const decorations = targetEditor.createDecorationsCollection([{ range, options: { description: 'symbol-navigate-action-highlight', className: 'symbolHighlight' } }]);
            setTimeout(() => {
                if (targetEditor.getModel() === modelNow) {
                    decorations.clear();
                }
            }, 350);
        }
        return targetEditor;
    }
    _openInPeek(target, model, range) {
        const controller = ReferencesController.get(target);
        if (controller && target.hasModel()) {
            controller.toggleWidget(range ?? target.getSelection(), createCancelablePromise(_ => Promise.resolve(model)), this.configuration.openInPeek);
        }
        else {
            model.dispose();
        }
    }
}
class DefinitionAction extends SymbolNavigationAction {
    async _getLocationModel(languageFeaturesService, model, position, token) {
        return (
             (new ReferencesModel(
                await getDefinitionsAtPosition(languageFeaturesService.definitionProvider, model, position, token),
                ( localizeWithPath(_moduleId, 1, 'Definitions'))
            ))
        );
    }
    _getNoResultFoundMessage(info) {
        return info && info.word
            ? ( localizeWithPath(_moduleId, 2, "No definition found for '{0}'", info.word))
            : ( localizeWithPath(_moduleId, 3, "No definition found"));
    }
    _getAlternativeCommand(editor) {
        return editor.getOption(EditorOption.gotoLocation).alternativeDefinitionCommand;
    }
    _getGoToPreference(editor) {
        return editor.getOption(EditorOption.gotoLocation).multipleDefinitions;
    }
}
registerAction2(class GoToDefinitionAction extends DefinitionAction {
    static { this.id = 'editor.action.revealDefinition'; }
    constructor() {
        super({
            openToSide: false,
            openInPeek: false,
            muteMessage: false
        }, {
            id: GoToDefinitionAction.id,
            title: {
                ...( localize2WithPath(_moduleId, 4, "Go to Definition")),
                mnemonicTitle: ( localizeWithPath(_moduleId, 5, "Go to &&Definition")),
            },
            precondition: EditorContextKeys.hasDefinitionProvider,
            keybinding: [{
                    when: EditorContextKeys.editorTextFocus,
                    primary: KeyCode.F12,
                    weight: KeybindingWeight.EditorContrib
                }, {
                    when: ( (ContextKeyExpr.and(EditorContextKeys.editorTextFocus, IsWebContext))),
                    primary: KeyMod$1.CtrlCmd | KeyCode.F12,
                    weight: KeybindingWeight.EditorContrib
                }],
            menu: [{
                    id: MenuId.EditorContext,
                    group: 'navigation',
                    order: 1.1
                }, {
                    id: MenuId.MenubarGoMenu,
                    precondition: null,
                    group: '4_symbol_nav',
                    order: 2,
                }]
        });
        CommandsRegistry.registerCommandAlias('editor.action.goToDeclaration', GoToDefinitionAction.id);
    }
});
registerAction2(class OpenDefinitionToSideAction extends DefinitionAction {
    static { this.id = 'editor.action.revealDefinitionAside'; }
    constructor() {
        super({
            openToSide: true,
            openInPeek: false,
            muteMessage: false
        }, {
            id: OpenDefinitionToSideAction.id,
            title: ( localize2WithPath(_moduleId, 6, "Open Definition to the Side")),
            precondition: ( (ContextKeyExpr.and(
                EditorContextKeys.hasDefinitionProvider,
                 (EditorContextKeys.isInEmbeddedEditor.toNegated())
            ))),
            keybinding: [{
                    when: EditorContextKeys.editorTextFocus,
                    primary: KeyChord(KeyMod$1.CtrlCmd | KeyCode.KeyK, KeyCode.F12),
                    weight: KeybindingWeight.EditorContrib
                }, {
                    when: ( (ContextKeyExpr.and(EditorContextKeys.editorTextFocus, IsWebContext))),
                    primary: KeyChord(KeyMod$1.CtrlCmd | KeyCode.KeyK, KeyMod$1.CtrlCmd | KeyCode.F12),
                    weight: KeybindingWeight.EditorContrib
                }]
        });
        CommandsRegistry.registerCommandAlias('editor.action.openDeclarationToTheSide', OpenDefinitionToSideAction.id);
    }
});
registerAction2(class PeekDefinitionAction extends DefinitionAction {
    static { this.id = 'editor.action.peekDefinition'; }
    constructor() {
        super({
            openToSide: false,
            openInPeek: true,
            muteMessage: false
        }, {
            id: PeekDefinitionAction.id,
            title: ( localize2WithPath(_moduleId, 7, "Peek Definition")),
            precondition: ( (ContextKeyExpr.and(
                EditorContextKeys.hasDefinitionProvider,
                PeekContext.notInPeekEditor,
                 (EditorContextKeys.isInEmbeddedEditor.toNegated())
            ))),
            keybinding: {
                when: EditorContextKeys.editorTextFocus,
                primary: KeyMod$1.Alt | KeyCode.F12,
                linux: { primary: KeyMod$1.CtrlCmd | KeyMod$1.Shift | KeyCode.F10 },
                weight: KeybindingWeight.EditorContrib
            },
            menu: {
                id: MenuId.EditorContextPeek,
                group: 'peek',
                order: 2
            }
        });
        CommandsRegistry.registerCommandAlias('editor.action.previewDeclaration', PeekDefinitionAction.id);
    }
});
class DeclarationAction extends SymbolNavigationAction {
    async _getLocationModel(languageFeaturesService, model, position, token) {
        return (
             (new ReferencesModel(
                await getDeclarationsAtPosition(languageFeaturesService.declarationProvider, model, position, token),
                ( localizeWithPath(_moduleId, 8, 'Declarations'))
            ))
        );
    }
    _getNoResultFoundMessage(info) {
        return info && info.word
            ? ( localizeWithPath(_moduleId, 9, "No declaration found for '{0}'", info.word))
            : ( localizeWithPath(_moduleId, 10, "No declaration found"));
    }
    _getAlternativeCommand(editor) {
        return editor.getOption(EditorOption.gotoLocation).alternativeDeclarationCommand;
    }
    _getGoToPreference(editor) {
        return editor.getOption(EditorOption.gotoLocation).multipleDeclarations;
    }
}
registerAction2(class GoToDeclarationAction extends DeclarationAction {
    static { this.id = 'editor.action.revealDeclaration'; }
    constructor() {
        super({
            openToSide: false,
            openInPeek: false,
            muteMessage: false
        }, {
            id: GoToDeclarationAction.id,
            title: {
                ...( localize2WithPath(_moduleId, 11, "Go to Declaration")),
                mnemonicTitle: ( localizeWithPath(_moduleId, 12, "Go to &&Declaration")),
            },
            precondition: ( (ContextKeyExpr.and(
                EditorContextKeys.hasDeclarationProvider,
                 (EditorContextKeys.isInEmbeddedEditor.toNegated())
            ))),
            menu: [{
                    id: MenuId.EditorContext,
                    group: 'navigation',
                    order: 1.3
                }, {
                    id: MenuId.MenubarGoMenu,
                    precondition: null,
                    group: '4_symbol_nav',
                    order: 3,
                }],
        });
    }
    _getNoResultFoundMessage(info) {
        return info && info.word
            ? ( localizeWithPath(_moduleId, 9, "No declaration found for '{0}'", info.word))
            : ( localizeWithPath(_moduleId, 10, "No declaration found"));
    }
});
registerAction2(class PeekDeclarationAction extends DeclarationAction {
    constructor() {
        super({
            openToSide: false,
            openInPeek: true,
            muteMessage: false
        }, {
            id: 'editor.action.peekDeclaration',
            title: ( localize2WithPath(_moduleId, 13, "Peek Declaration")),
            precondition: ( (ContextKeyExpr.and(
                EditorContextKeys.hasDeclarationProvider,
                PeekContext.notInPeekEditor,
                 (EditorContextKeys.isInEmbeddedEditor.toNegated())
            ))),
            menu: {
                id: MenuId.EditorContextPeek,
                group: 'peek',
                order: 3
            }
        });
    }
});
class TypeDefinitionAction extends SymbolNavigationAction {
    async _getLocationModel(languageFeaturesService, model, position, token) {
        return (
             (new ReferencesModel(
                await getTypeDefinitionsAtPosition(languageFeaturesService.typeDefinitionProvider, model, position, token),
                ( localizeWithPath(_moduleId, 14, 'Type Definitions'))
            ))
        );
    }
    _getNoResultFoundMessage(info) {
        return info && info.word
            ? ( localizeWithPath(_moduleId, 15, "No type definition found for '{0}'", info.word))
            : ( localizeWithPath(_moduleId, 16, "No type definition found"));
    }
    _getAlternativeCommand(editor) {
        return editor.getOption(EditorOption.gotoLocation).alternativeTypeDefinitionCommand;
    }
    _getGoToPreference(editor) {
        return editor.getOption(EditorOption.gotoLocation).multipleTypeDefinitions;
    }
}
registerAction2(class GoToTypeDefinitionAction extends TypeDefinitionAction {
    static { this.ID = 'editor.action.goToTypeDefinition'; }
    constructor() {
        super({
            openToSide: false,
            openInPeek: false,
            muteMessage: false
        }, {
            id: GoToTypeDefinitionAction.ID,
            title: {
                ...( localize2WithPath(_moduleId, 17, "Go to Type Definition")),
                mnemonicTitle: ( localizeWithPath(_moduleId, 18, "Go to &&Type Definition")),
            },
            precondition: EditorContextKeys.hasTypeDefinitionProvider,
            keybinding: {
                when: EditorContextKeys.editorTextFocus,
                primary: 0,
                weight: KeybindingWeight.EditorContrib
            },
            menu: [{
                    id: MenuId.EditorContext,
                    group: 'navigation',
                    order: 1.4
                }, {
                    id: MenuId.MenubarGoMenu,
                    precondition: null,
                    group: '4_symbol_nav',
                    order: 3,
                }]
        });
    }
});
registerAction2(class PeekTypeDefinitionAction extends TypeDefinitionAction {
    static { this.ID = 'editor.action.peekTypeDefinition'; }
    constructor() {
        super({
            openToSide: false,
            openInPeek: true,
            muteMessage: false
        }, {
            id: PeekTypeDefinitionAction.ID,
            title: ( localize2WithPath(_moduleId, 19, "Peek Type Definition")),
            precondition: ( (ContextKeyExpr.and(
                EditorContextKeys.hasTypeDefinitionProvider,
                PeekContext.notInPeekEditor,
                 (EditorContextKeys.isInEmbeddedEditor.toNegated())
            ))),
            menu: {
                id: MenuId.EditorContextPeek,
                group: 'peek',
                order: 4
            }
        });
    }
});
class ImplementationAction extends SymbolNavigationAction {
    async _getLocationModel(languageFeaturesService, model, position, token) {
        return (
             (new ReferencesModel(
                await getImplementationsAtPosition(languageFeaturesService.implementationProvider, model, position, token),
                ( localizeWithPath(_moduleId, 20, 'Implementations'))
            ))
        );
    }
    _getNoResultFoundMessage(info) {
        return info && info.word
            ? ( localizeWithPath(_moduleId, 21, "No implementation found for '{0}'", info.word))
            : ( localizeWithPath(_moduleId, 22, "No implementation found"));
    }
    _getAlternativeCommand(editor) {
        return editor.getOption(EditorOption.gotoLocation).alternativeImplementationCommand;
    }
    _getGoToPreference(editor) {
        return editor.getOption(EditorOption.gotoLocation).multipleImplementations;
    }
}
registerAction2(class GoToImplementationAction extends ImplementationAction {
    static { this.ID = 'editor.action.goToImplementation'; }
    constructor() {
        super({
            openToSide: false,
            openInPeek: false,
            muteMessage: false
        }, {
            id: GoToImplementationAction.ID,
            title: {
                ...( localize2WithPath(_moduleId, 23, "Go to Implementations")),
                mnemonicTitle: ( localizeWithPath(_moduleId, 24, "Go to &&Implementations")),
            },
            precondition: EditorContextKeys.hasImplementationProvider,
            keybinding: {
                when: EditorContextKeys.editorTextFocus,
                primary: KeyMod$1.CtrlCmd | KeyCode.F12,
                weight: KeybindingWeight.EditorContrib
            },
            menu: [{
                    id: MenuId.EditorContext,
                    group: 'navigation',
                    order: 1.45
                }, {
                    id: MenuId.MenubarGoMenu,
                    precondition: null,
                    group: '4_symbol_nav',
                    order: 4,
                }]
        });
    }
});
registerAction2(class PeekImplementationAction extends ImplementationAction {
    static { this.ID = 'editor.action.peekImplementation'; }
    constructor() {
        super({
            openToSide: false,
            openInPeek: true,
            muteMessage: false
        }, {
            id: PeekImplementationAction.ID,
            title: ( localize2WithPath(_moduleId, 25, "Peek Implementations")),
            precondition: ( (ContextKeyExpr.and(
                EditorContextKeys.hasImplementationProvider,
                PeekContext.notInPeekEditor,
                 (EditorContextKeys.isInEmbeddedEditor.toNegated())
            ))),
            keybinding: {
                when: EditorContextKeys.editorTextFocus,
                primary: KeyMod$1.CtrlCmd | KeyMod$1.Shift | KeyCode.F12,
                weight: KeybindingWeight.EditorContrib
            },
            menu: {
                id: MenuId.EditorContextPeek,
                group: 'peek',
                order: 5
            }
        });
    }
});
class ReferencesAction extends SymbolNavigationAction {
    _getNoResultFoundMessage(info) {
        return info
            ? ( localizeWithPath(_moduleId, 26, "No references found for '{0}'", info.word))
            : ( localizeWithPath(_moduleId, 27, "No references found"));
    }
    _getAlternativeCommand(editor) {
        return editor.getOption(EditorOption.gotoLocation).alternativeReferenceCommand;
    }
    _getGoToPreference(editor) {
        return editor.getOption(EditorOption.gotoLocation).multipleReferences;
    }
}
registerAction2(class GoToReferencesAction extends ReferencesAction {
    constructor() {
        super({
            openToSide: false,
            openInPeek: false,
            muteMessage: false
        }, {
            id: 'editor.action.goToReferences',
            title: {
                ...( localize2WithPath(_moduleId, 28, "Go to References")),
                mnemonicTitle: ( localizeWithPath(_moduleId, 29, "Go to &&References")),
            },
            precondition: ( (ContextKeyExpr.and(
                EditorContextKeys.hasReferenceProvider,
                PeekContext.notInPeekEditor,
                 (EditorContextKeys.isInEmbeddedEditor.toNegated())
            ))),
            keybinding: {
                when: EditorContextKeys.editorTextFocus,
                primary: KeyMod$1.Shift | KeyCode.F12,
                weight: KeybindingWeight.EditorContrib
            },
            menu: [{
                    id: MenuId.EditorContext,
                    group: 'navigation',
                    order: 1.45
                }, {
                    id: MenuId.MenubarGoMenu,
                    precondition: null,
                    group: '4_symbol_nav',
                    order: 5,
                }]
        });
    }
    async _getLocationModel(languageFeaturesService, model, position, token) {
        return (
             (new ReferencesModel(
                await getReferencesAtPosition(languageFeaturesService.referenceProvider, model, position, true, token),
                ( localizeWithPath(_moduleId, 30, 'References'))
            ))
        );
    }
});
registerAction2(class PeekReferencesAction extends ReferencesAction {
    constructor() {
        super({
            openToSide: false,
            openInPeek: true,
            muteMessage: false
        }, {
            id: 'editor.action.referenceSearch.trigger',
            title: ( localize2WithPath(_moduleId, 31, "Peek References")),
            precondition: ( (ContextKeyExpr.and(
                EditorContextKeys.hasReferenceProvider,
                PeekContext.notInPeekEditor,
                 (EditorContextKeys.isInEmbeddedEditor.toNegated())
            ))),
            menu: {
                id: MenuId.EditorContextPeek,
                group: 'peek',
                order: 6
            }
        });
    }
    async _getLocationModel(languageFeaturesService, model, position, token) {
        return (
             (new ReferencesModel(
                await getReferencesAtPosition(languageFeaturesService.referenceProvider, model, position, false, token),
                ( localizeWithPath(_moduleId, 30, 'References'))
            ))
        );
    }
});
class GenericGoToLocationAction extends SymbolNavigationAction {
    constructor(config, _references, _gotoMultipleBehaviour) {
        super(config, {
            id: 'editor.action.goToLocation',
            title: ( localize2WithPath(_moduleId, 32, "Go to Any Symbol")),
            precondition: ( (ContextKeyExpr.and(
                PeekContext.notInPeekEditor,
                 (EditorContextKeys.isInEmbeddedEditor.toNegated())
            ))),
        });
        this._references = _references;
        this._gotoMultipleBehaviour = _gotoMultipleBehaviour;
    }
    async _getLocationModel(languageFeaturesService, _model, _position, _token) {
        return (
             (new ReferencesModel(this._references, ( localizeWithPath(_moduleId, 33, 'Locations'))))
        );
    }
    _getNoResultFoundMessage(info) {
        return info && ( localizeWithPath(_moduleId, 34, "No results for '{0}'", info.word)) || '';
    }
    _getGoToPreference(editor) {
        return this._gotoMultipleBehaviour ?? editor.getOption(EditorOption.gotoLocation).multipleReferences;
    }
    _getAlternativeCommand() { return ''; }
}
CommandsRegistry.registerCommand({
    id: 'editor.action.goToLocations',
    metadata: {
        description: 'Go to locations from a position in a file',
        args: [
            { name: 'uri', description: 'The text document in which to start', constraint: URI },
            { name: 'position', description: 'The position at which to start', constraint: Position.isIPosition },
            { name: 'locations', description: 'An array of locations.', constraint: Array },
            { name: 'multiple', description: 'Define what to do when having multiple results, either `peek`, `gotoAndPeek`, or `goto`' },
            { name: 'noResultsMessage', description: 'Human readable message that shows when locations is empty.' },
        ]
    },
    handler: async (accessor, resource, position, references, multiple, noResultsMessage, openInPeek) => {
        assertType(URI.isUri(resource));
        assertType(Position.isIPosition(position));
        assertType(Array.isArray(references));
        assertType(typeof multiple === 'undefined' || typeof multiple === 'string');
        assertType(typeof openInPeek === 'undefined' || typeof openInPeek === 'boolean');
        const editorService = accessor.get(ICodeEditorService);
        const editor = await editorService.openCodeEditor({ resource }, editorService.getFocusedCodeEditor());
        if (isCodeEditor(editor)) {
            editor.setPosition(position);
            editor.revealPositionInCenterIfOutsideViewport(position, ScrollType.Smooth);
            return editor.invokeWithinContext(accessor => {
                const command = new (class extends GenericGoToLocationAction {
                    _getNoResultFoundMessage(info) {
                        return noResultsMessage || super._getNoResultFoundMessage(info);
                    }
                })({
                    muteMessage: !Boolean(noResultsMessage),
                    openInPeek: Boolean(openInPeek),
                    openToSide: false
                }, references, multiple);
                accessor.get(IInstantiationService).invokeFunction(command.run.bind(command), editor);
            });
        }
    }
});
CommandsRegistry.registerCommand({
    id: 'editor.action.peekLocations',
    metadata: {
        description: 'Peek locations from a position in a file',
        args: [
            { name: 'uri', description: 'The text document in which to start', constraint: URI },
            { name: 'position', description: 'The position at which to start', constraint: Position.isIPosition },
            { name: 'locations', description: 'An array of locations.', constraint: Array },
            { name: 'multiple', description: 'Define what to do when having multiple results, either `peek`, `gotoAndPeek`, or `goto`' },
        ]
    },
    handler: async (accessor, resource, position, references, multiple) => {
        accessor.get(ICommandService).executeCommand('editor.action.goToLocations', resource, position, references, multiple, undefined, true);
    }
});
CommandsRegistry.registerCommand({
    id: 'editor.action.findReferences',
    handler: (accessor, resource, position) => {
        assertType(URI.isUri(resource));
        assertType(Position.isIPosition(position));
        const languageFeaturesService = accessor.get(ILanguageFeaturesService);
        const codeEditorService = accessor.get(ICodeEditorService);
        return codeEditorService.openCodeEditor({ resource }, codeEditorService.getFocusedCodeEditor()).then(control => {
            if (!isCodeEditor(control) || !control.hasModel()) {
                return undefined;
            }
            const controller = ReferencesController.get(control);
            if (!controller) {
                return undefined;
            }
            const references = createCancelablePromise(token => getReferencesAtPosition(languageFeaturesService.referenceProvider, control.getModel(), Position.lift(position), false, token).then(references => ( (new ReferencesModel(references, ( localizeWithPath(_moduleId, 30, 'References')))))));
            const range = ( (new Range(position.lineNumber, position.column, position.lineNumber, position.column)));
            return Promise.resolve(controller.toggleWidget(range, references, false));
        });
    }
});
CommandsRegistry.registerCommandAlias('editor.action.showReferences', 'editor.action.peekLocations');
export { DefinitionAction, SymbolNavigationAction, SymbolNavigationAnchor };
