
import { __decorate, __param } from '../../../../../../../external/tslib/tslib.es6.js';
import { $ as $$1, append } from '../../../../base/browser/dom.js';
import { HighlightedLabel } from '../../../../base/browser/ui/highlightedlabel/highlightedLabel.js';
import { toAction } from '../../../../base/common/actions.js';
import { coalesce } from '../../../../base/common/arrays.js';
import { RunOnceScheduler } from '../../../../base/common/async.js';
import { CancellationTokenSource } from '../../../../base/common/cancellation.js';
import { Codicon } from '../../../../base/common/codicons.js';
import { createMatches } from '../../../../base/common/filters.js';
import { toDisposable } from '../../../../base/common/lifecycle.js';
import { ThemeIcon } from '../../../../base/common/themables.js';
import { localize } from '../../../../nls.js';
import { getContextMenuActions } from '../../../../platform/actions/browser/menuEntryActionViewItem.js';
import { MenuId, registerAction2 } from '../../../../platform/actions/common/actions.js';
import { IMenuService } from '../../../../platform/actions/common/actions.service.js';
import { IClipboardService } from '../../../../platform/clipboard/common/clipboardService.service.js';
import { CommandsRegistry } from '../../../../platform/commands/common/commands.js';
import { IConfigurationService } from '../../../../platform/configuration/common/configuration.service.js';
import { ContextKeyExpr } from '../../../../platform/contextkey/common/contextkey.js';
import { IContextKeyService } from '../../../../platform/contextkey/common/contextkey.service.js';
import { IContextMenuService, IContextViewService } from '../../../../platform/contextview/browser/contextView.service.js';
import { IHoverService } from '../../../../platform/hover/browser/hover.service.js';
import { IInstantiationService } from '../../../../platform/instantiation/common/instantiation.js';
import { IKeybindingService } from '../../../../platform/keybinding/common/keybinding.service.js';
import { WorkbenchAsyncDataTree } from '../../../../platform/list/browser/listService.js';
import { INotificationService } from '../../../../platform/notification/common/notification.service.js';
import { IOpenerService } from '../../../../platform/opener/common/opener.service.js';
import { ProgressLocation } from '../../../../platform/progress/common/progress.js';
import { ITelemetryService } from '../../../../platform/telemetry/common/telemetry.service.js';
import { IThemeService } from '../../../../platform/theme/common/themeService.service.js';
import { ViewPane, ViewAction } from '../../../browser/parts/views/viewPane.js';
import { IViewDescriptorService } from '../../../common/views.service.js';
import { SIDE_GROUP } from '../../../services/editor/common/editorService.js';
import { IEditorService } from '../../../services/editor/common/editorService.service.js';
import { IExtensionService } from '../../../services/extensions/common/extensions.service.js';
import { IViewsService } from '../../../services/views/common/viewsService.service.js';
import { IExtensionsWorkbenchService } from '../../extensions/common/extensions.service.js';
import { CONTEXT_VARIABLES_FOCUSED, CONTEXT_BREAK_WHEN_VALUE_CHANGES_SUPPORTED, CONTEXT_BREAK_WHEN_VALUE_IS_ACCESSED_SUPPORTED, CONTEXT_BREAK_WHEN_VALUE_IS_READ_SUPPORTED, DebugVisualizationType, WATCH_VIEW_ID, VARIABLES_VIEW_ID } from '../common/debug.js';
import { IDebugService } from '../common/debug.service.js';
import { getContextForVariable } from '../common/debugContext.js';
import { Variable, VisualizedExpression, Scope, Expression, StackFrame, ErrorScope, getUriForDebugMemory } from '../common/debugModel.js';
import { IDebugVisualizerService } from '../common/debugVisualizers.service.js';
import { renderViewTree, expressionAndScopeLabelProvider, AbstractExpressionDataSource, AbstractExpressionsRenderer } from './baseDebugView.js';
import { setDataBreakpointInfoResponse, COPY_VALUE_ID, COPY_VALUE_LABEL, COPY_EVALUATE_PATH_ID, COPY_EVALUATE_PATH_LABEL, ADD_TO_WATCH_ID, ADD_TO_WATCH_LABEL } from './debugCommands.js';
import { DebugExpressionRenderer } from './debugExpressionRenderer.js';

var VisualizedVariableRenderer_1, VariablesRenderer_1;
const $ = $$1;
let forgetScopes = true;
let variableInternalContext;
let VariablesView = class VariablesView extends ViewPane {
    get treeSelection() {
        return this.tree.getSelection();
    }
    constructor(
        options,
        contextMenuService,
        debugService,
        keybindingService,
        configurationService,
        instantiationService,
        viewDescriptorService,
        contextKeyService,
        openerService,
        themeService,
        hoverService,
        menuService
    ) {
        super(
            options,
            keybindingService,
            contextMenuService,
            configurationService,
            contextKeyService,
            viewDescriptorService,
            instantiationService,
            openerService,
            themeService,
            hoverService
        );
        this.debugService = debugService;
        this.menuService = menuService;
        this.needsRefresh = false;
        this.savedViewState = ( new Map());
        this.autoExpandedScopes = ( new Set());
        this.updateTreeScheduler = this._register(( new RunOnceScheduler(async () => {
            const stackFrame = this.debugService.getViewModel().focusedStackFrame;
            this.needsRefresh = false;
            const input = this.tree.getInput();
            if (input) {
                this.savedViewState.set(input.getId(), this.tree.getViewState());
            }
            if (!stackFrame) {
                await this.tree.setInput(null);
                return;
            }
            const viewState = this.savedViewState.get(stackFrame.getId());
            await this.tree.setInput(stackFrame, viewState);
            const scopes = await stackFrame.getScopes();
            const toExpand = scopes.find(s => !s.expensive);
            if (toExpand && this.tree.hasNode(toExpand)) {
                this.autoExpandedScopes.add(toExpand.getId());
                await this.tree.expand(toExpand);
            }
        }, 400)));
    }
    renderBody(container) {
        super.renderBody(container);
        this.element.classList.add("debug-pane");
        container.classList.add("debug-variables");
        const treeContainer = renderViewTree(container);
        const expressionRenderer = this.instantiationService.createInstance(DebugExpressionRenderer);
        this.tree = this.instantiationService.createInstance(WorkbenchAsyncDataTree, "VariablesView", treeContainer, ( new VariablesDelegate()), [
            this.instantiationService.createInstance(VariablesRenderer, expressionRenderer),
            this.instantiationService.createInstance(VisualizedVariableRenderer, expressionRenderer),
            ( new ScopesRenderer()),
            ( new ScopeErrorRenderer())
        ], this.instantiationService.createInstance(VariablesDataSource), {
            accessibilityProvider: ( new VariablesAccessibilityProvider()),
            identityProvider: {
                getId: element => element.getId()
            },
            keyboardNavigationLabelProvider: expressionAndScopeLabelProvider,
            overrideStyles: this.getLocationBasedColors().listOverrideStyles
        });
        this._register(
            VisualizedVariableRenderer.rendererOnVisualizationRange(this.debugService.getViewModel(), this.tree)
        );
        this.tree.setInput(this.debugService.getViewModel().focusedStackFrame ?? null);
        CONTEXT_VARIABLES_FOCUSED.bindTo(this.tree.contextKeyService);
        this._register(this.debugService.getViewModel().onDidFocusStackFrame(sf => {
            if (!this.isBodyVisible()) {
                this.needsRefresh = true;
                return;
            }
            const timeout = sf.explicit ? 0 : undefined;
            this.updateTreeScheduler.schedule(timeout);
        }));
        this._register(this.debugService.getViewModel().onWillUpdateViews(() => {
            const stackFrame = this.debugService.getViewModel().focusedStackFrame;
            if (stackFrame && forgetScopes) {
                stackFrame.forgetScopes();
            }
            forgetScopes = true;
            this.tree.updateChildren();
        }));
        this._register(this.tree);
        this._register(this.tree.onMouseDblClick(e => this.onMouseDblClick(e)));
        this._register(this.tree.onContextMenu(async e => await this.onContextMenu(e)));
        this._register(this.onDidChangeBodyVisibility(visible => {
            if (visible && this.needsRefresh) {
                this.updateTreeScheduler.schedule();
            }
        }));
        let horizontalScrolling;
        this._register(this.debugService.getViewModel().onDidSelectExpression(e => {
            const variable = e?.expression;
            if (variable && this.tree.hasNode(variable)) {
                horizontalScrolling = this.tree.options.horizontalScrolling;
                if (horizontalScrolling) {
                    this.tree.updateOptions({
                        horizontalScrolling: false
                    });
                }
                this.tree.rerender(variable);
            } else if (!e && horizontalScrolling !== undefined) {
                this.tree.updateOptions({
                    horizontalScrolling: horizontalScrolling
                });
                horizontalScrolling = undefined;
            }
        }));
        this._register(this.debugService.getViewModel().onDidEvaluateLazyExpression(async e => {
            if (e instanceof Variable && this.tree.hasNode(e)) {
                await this.tree.updateChildren(e, false, true);
                await this.tree.expand(e);
            }
        }));
        this._register(this.debugService.onDidEndSession(() => {
            this.savedViewState.clear();
            this.autoExpandedScopes.clear();
        }));
    }
    layoutBody(width, height) {
        super.layoutBody(height, width);
        this.tree.layout(width, height);
    }
    focus() {
        super.focus();
        this.tree.domFocus();
    }
    collapseAll() {
        this.tree.collapseAll();
    }
    onMouseDblClick(e) {
        if (this.canSetExpressionValue(e.element)) {
            this.debugService.getViewModel().setSelectedExpression(e.element, false);
        }
    }
    canSetExpressionValue(e) {
        const session = this.debugService.getViewModel().focusedSession;
        if (!session) {
            return false;
        }
        if (e instanceof VisualizedExpression) {
            return !!e.treeItem.canEdit;
        }
        if (!session.capabilities?.supportsSetVariable && !session.capabilities?.supportsSetExpression) {
            return false;
        }
        return e instanceof Variable && !e.presentationHint?.attributes?.includes("readOnly") && !e.presentationHint?.lazy;
    }
    async onContextMenu(e) {
        const element = e.element;
        if (element instanceof Scope) {
            return this.openContextMenuForScope(e, element);
        }
        if (!(element instanceof Variable) || !element.value) {
            return;
        }
        return openContextMenuForVariableTreeElement(
            this.contextKeyService,
            this.menuService,
            this.contextMenuService,
            MenuId.DebugVariablesContext,
            e
        );
    }
    openContextMenuForScope(e, scope) {
        const context = {
            scope: {
                name: scope.name
            }
        };
        const menu = this.menuService.getMenuActions(MenuId.DebugScopesContext, this.contextKeyService, {
            arg: context,
            shouldForwardArgs: false
        });
        const {
            secondary
        } = getContextMenuActions(menu, "inline");
        this.contextMenuService.showContextMenu({
            getAnchor: () => e.anchor,
            getActions: () => secondary
        });
    }
};
VariablesView = ( __decorate([( __param(1, IContextMenuService)), ( __param(2, IDebugService)), ( __param(3, IKeybindingService)), ( __param(4, IConfigurationService)), ( __param(5, IInstantiationService)), ( __param(6, IViewDescriptorService)), ( __param(7, IContextKeyService)), ( __param(8, IOpenerService)), ( __param(9, IThemeService)), ( __param(10, IHoverService)), ( __param(11, IMenuService))], VariablesView));
async function openContextMenuForVariableTreeElement(parentContextKeyService, menuService, contextMenuService, menuId, e) {
    const variable = e.element;
    if (!(variable instanceof Variable) || !variable.value) {
        return;
    }
    const contextKeyService = await getContextForVariableMenuWithDataAccess(parentContextKeyService, variable);
    const context = getVariablesContext(variable);
    const menu = menuService.getMenuActions(menuId, contextKeyService, {
        arg: context,
        shouldForwardArgs: false
    });
    const {
        secondary
    } = getContextMenuActions(menu, "inline");
    contextMenuService.showContextMenu({
        getAnchor: () => e.anchor,
        getActions: () => secondary
    });
}
const getVariablesContext = variable => ({
    sessionId: variable.getSession()?.getId(),
    container: variable.parent instanceof Expression ? {
        expression: variable.parent.name
    } : variable.parent.toDebugProtocolObject(),
    variable: variable.toDebugProtocolObject()
});
async function getContextForVariableMenuWithDataAccess(parentContext, variable) {
    const session = variable.getSession();
    if (!session || !session.capabilities.supportsDataBreakpoints) {
        return getContextForVariableMenuBase(parentContext, variable);
    }
    const contextKeys = [];
    const dataBreakpointInfoResponse = await session.dataBreakpointInfo(variable.name, variable.parent.reference);
    const dataBreakpointId = dataBreakpointInfoResponse?.dataId;
    const dataBreakpointAccessTypes = dataBreakpointInfoResponse?.accessTypes;
    setDataBreakpointInfoResponse(dataBreakpointInfoResponse);
    if (!dataBreakpointAccessTypes) {
        contextKeys.push([CONTEXT_BREAK_WHEN_VALUE_CHANGES_SUPPORTED.key, !!dataBreakpointId]);
    } else {
        for (const accessType of dataBreakpointAccessTypes) {
            switch (accessType) {
            case "read":
                contextKeys.push([CONTEXT_BREAK_WHEN_VALUE_IS_READ_SUPPORTED.key, !!dataBreakpointId]);
                break;
            case "write":
                contextKeys.push([CONTEXT_BREAK_WHEN_VALUE_CHANGES_SUPPORTED.key, !!dataBreakpointId]);
                break;
            case "readWrite":
                contextKeys.push([CONTEXT_BREAK_WHEN_VALUE_IS_ACCESSED_SUPPORTED.key, !!dataBreakpointId]);
                break;
            }
        }
    }
    return getContextForVariableMenuBase(parentContext, variable, contextKeys);
}
function getContextForVariableMenuBase(parentContext, variable, additionalContext = []) {
    variableInternalContext = variable;
    return getContextForVariable(parentContext, variable, additionalContext);
}
function isStackFrame(obj) {
    return obj instanceof StackFrame;
}
class VariablesDataSource extends AbstractExpressionDataSource {
    hasChildren(element) {
        if (!element) {
            return false;
        }
        if (isStackFrame(element)) {
            return true;
        }
        return element.hasChildren;
    }
    doGetChildren(element) {
        if (isStackFrame(element)) {
            return element.getScopes();
        }
        return element.getChildren();
    }
}
class VariablesDelegate {
    getHeight(element) {
        return 22;
    }
    getTemplateId(element) {
        if (element instanceof ErrorScope) {
            return ScopeErrorRenderer.ID;
        }
        if (element instanceof Scope) {
            return ScopesRenderer.ID;
        }
        if (element instanceof VisualizedExpression) {
            return VisualizedVariableRenderer.ID;
        }
        return VariablesRenderer.ID;
    }
}
class ScopesRenderer {
    static {
        this.ID = "scope";
    }
    get templateId() {
        return ScopesRenderer.ID;
    }
    renderTemplate(container) {
        const name = append(container, $(".scope"));
        const label = ( new HighlightedLabel(name));
        return {
            name,
            label
        };
    }
    renderElement(element, index, templateData) {
        templateData.label.set(element.element.name, createMatches(element.filterData));
    }
    disposeTemplate(templateData) {
        templateData.label.dispose();
    }
}
class ScopeErrorRenderer {
    static {
        this.ID = "scopeError";
    }
    get templateId() {
        return ScopeErrorRenderer.ID;
    }
    renderTemplate(container) {
        const wrapper = append(container, $(".scope"));
        const error = append(wrapper, $(".error"));
        return {
            error
        };
    }
    renderElement(element, index, templateData) {
        templateData.error.innerText = element.element.name;
    }
    disposeTemplate() {}
}
let VisualizedVariableRenderer = class VisualizedVariableRenderer extends AbstractExpressionsRenderer {
    static {
        VisualizedVariableRenderer_1 = this;
    }
    static {
        this.ID = "viz";
    }
    static rendererOnVisualizationRange(model, tree) {
        return model.onDidChangeVisualization((
            {
                original
            }
        ) => {
            if (!tree.hasNode(original)) {
                return;
            }
            const parent = tree.getParentElement(original);
            tree.updateChildren(parent, false, false);
        });
    }
    constructor(
        expressionRenderer,
        debugService,
        contextViewService,
        hoverService,
        menuService,
        contextKeyService
    ) {
        super(debugService, contextViewService, hoverService);
        this.expressionRenderer = expressionRenderer;
        this.menuService = menuService;
        this.contextKeyService = contextKeyService;
    }
    get templateId() {
        return VisualizedVariableRenderer_1.ID;
    }
    renderElement(node, index, data) {
        data.elementDisposable.clear();
        super.renderExpressionElement(node.element, node, data);
    }
    renderExpression(expression, data, highlights) {
        const viz = expression;
        let text = viz.name;
        if (viz.value && typeof viz.name === "string") {
            text += ":";
        }
        data.label.set(text, highlights, viz.name);
        data.elementDisposable.add(this.expressionRenderer.renderValue(data.value, viz, {
            showChanged: false,
            maxValueLength: 1024,
            colorize: true,
            session: expression.getSession()
        }));
    }
    getInputBoxOptions(expression) {
        const viz = expression;
        return {
            initialValue: expression.value,
            ariaLabel: ( localize(9348, "Type new variable value")),
            validationOptions: {
                validation: () => viz.errorMessage ? ({
                    content: viz.errorMessage
                }) : null
            },
            onFinish: (value, success) => {
                viz.errorMessage = undefined;
                if (success) {
                    viz.edit(value).then(() => {
                        forgetScopes = false;
                        this.debugService.getViewModel().updateViews();
                    });
                }
            }
        };
    }
    renderActionBar(actionBar, expression, _data) {
        const viz = expression;
        const contextKeyService = viz.original ? getContextForVariableMenuBase(this.contextKeyService, viz.original) : this.contextKeyService;
        const context = viz.original ? getVariablesContext(viz.original) : undefined;
        const menu = this.menuService.getMenuActions(MenuId.DebugVariablesContext, contextKeyService, {
            arg: context,
            shouldForwardArgs: false
        });
        const {
            primary
        } = getContextMenuActions(menu, "inline");
        if (viz.original) {
            const action = toAction({
                id: "debugViz",
                label: ( localize(9349, "Remove Visualizer")),
                class: ThemeIcon.asClassName(Codicon.eye),
                run: () => this.debugService.getViewModel().setVisualizedExpression(viz.original, undefined)
            });
            action.checked = true;
            primary.push(action);
            actionBar.domNode.style.display = "initial";
        }
        actionBar.clear();
        actionBar.context = context;
        actionBar.push(primary, {
            icon: true,
            label: false
        });
    }
};
VisualizedVariableRenderer = VisualizedVariableRenderer_1 = ( __decorate([( __param(1, IDebugService)), ( __param(2, IContextViewService)), ( __param(3, IHoverService)), ( __param(4, IMenuService)), ( __param(5, IContextKeyService))], VisualizedVariableRenderer));
let VariablesRenderer = class VariablesRenderer extends AbstractExpressionsRenderer {
    static {
        VariablesRenderer_1 = this;
    }
    static {
        this.ID = "variable";
    }
    constructor(
        expressionRenderer,
        menuService,
        contextKeyService,
        visualization,
        contextMenuService,
        debugService,
        contextViewService,
        hoverService
    ) {
        super(debugService, contextViewService, hoverService);
        this.expressionRenderer = expressionRenderer;
        this.menuService = menuService;
        this.contextKeyService = contextKeyService;
        this.visualization = visualization;
        this.contextMenuService = contextMenuService;
    }
    get templateId() {
        return VariablesRenderer_1.ID;
    }
    renderExpression(expression, data, highlights) {
        data.elementDisposable.add(this.expressionRenderer.renderVariable(data, expression, {
            highlights,
            showChanged: true
        }));
    }
    renderElement(node, index, data) {
        data.elementDisposable.clear();
        super.renderExpressionElement(node.element, node, data);
    }
    getInputBoxOptions(expression) {
        const variable = expression;
        return {
            initialValue: expression.value,
            ariaLabel: ( localize(9348, "Type new variable value")),
            validationOptions: {
                validation: () => variable.errorMessage ? ({
                    content: variable.errorMessage
                }) : null
            },
            onFinish: (value, success) => {
                variable.errorMessage = undefined;
                const focusedStackFrame = this.debugService.getViewModel().focusedStackFrame;
                if (success && variable.value !== value && focusedStackFrame) {
                    variable.setVariable(value, focusedStackFrame).then(() => {
                        forgetScopes = false;
                        this.debugService.getViewModel().updateViews();
                    });
                }
            }
        };
    }
    renderActionBar(actionBar, expression, data) {
        const variable = expression;
        const contextKeyService = getContextForVariableMenuBase(this.contextKeyService, variable);
        const context = getVariablesContext(variable);
        const menu = this.menuService.getMenuActions(MenuId.DebugVariablesContext, contextKeyService, {
            arg: context,
            shouldForwardArgs: false
        });
        const {
            primary
        } = getContextMenuActions(menu, "inline");
        actionBar.clear();
        actionBar.context = context;
        actionBar.push(primary, {
            icon: true,
            label: false
        });
        const cts = ( new CancellationTokenSource());
        data.elementDisposable.add(toDisposable(() => cts.dispose(true)));
        this.visualization.getApplicableFor(expression, cts.token).then(result => {
            data.elementDisposable.add(result);
            const originalExpression = (expression instanceof VisualizedExpression && expression.original) || expression;
            const actions = ( result.object.map(v => toAction({
                id: "debugViz",
                label: v.name,
                class: v.iconClass || "debug-viz-icon",
                run: this.useVisualizer(v, originalExpression, cts.token)
            })));
            if (actions.length === 0)
                ; else if (actions.length === 1) {
                actionBar.push(actions[0], {
                    icon: true,
                    label: false
                });
            } else {
                actionBar.push(toAction({
                    id: "debugViz",
                    label: ( localize(9350, "Visualize Variable...")),
                    class: ThemeIcon.asClassName(Codicon.eye),
                    run: () => this.pickVisualizer(actions, originalExpression, data)
                }), {
                    icon: true,
                    label: false
                });
            }
        });
    }
    pickVisualizer(actions, expression, data) {
        this.contextMenuService.showContextMenu({
            getAnchor: () => data.actionBar.getContainer(),
            getActions: () => actions
        });
    }
    useVisualizer(viz, expression, token) {
        return async () => {
            const resolved = await viz.resolve(token);
            if (token.isCancellationRequested) {
                return;
            }
            if (resolved.type === DebugVisualizationType.Command) {
                viz.execute();
            } else {
                const replacement = await this.visualization.getVisualizedNodeFor(resolved.id, expression);
                if (replacement) {
                    this.debugService.getViewModel().setVisualizedExpression(expression, replacement);
                }
            }
        };
    }
};
VariablesRenderer = VariablesRenderer_1 = ( __decorate([( __param(1, IMenuService)), ( __param(2, IContextKeyService)), ( __param(3, IDebugVisualizerService)), ( __param(4, IContextMenuService)), ( __param(5, IDebugService)), ( __param(6, IContextViewService)), ( __param(7, IHoverService))], VariablesRenderer));
class VariablesAccessibilityProvider {
    getWidgetAriaLabel() {
        return localize(9351, "Debug Variables");
    }
    getAriaLabel(element) {
        if (element instanceof Scope) {
            return localize(9352, "Scope {0}", element.name);
        }
        if (element instanceof Variable) {
            return localize(9353, "{0}, value {1}", element.name, element.value);
        }
        return null;
    }
}
const SET_VARIABLE_ID = "debug.setVariable";
CommandsRegistry.registerCommand({
    id: SET_VARIABLE_ID,
    handler: accessor => {
        const debugService = accessor.get(IDebugService);
        debugService.getViewModel().setSelectedExpression(variableInternalContext, false);
    }
});
CommandsRegistry.registerCommand({
    metadata: {
        description: COPY_VALUE_LABEL
    },
    id: COPY_VALUE_ID,
    handler: async (accessor, arg, ctx) => {
        const debugService = accessor.get(IDebugService);
        const clipboardService = accessor.get(IClipboardService);
        let elementContext = "";
        let elements;
        if (!arg) {
            const viewService = accessor.get(IViewsService);
            const focusedView = viewService.getFocusedView();
            let view;
            if (focusedView?.id === WATCH_VIEW_ID) {
                view = viewService.getActiveViewWithId(WATCH_VIEW_ID);
                elementContext = "watch";
            } else if (focusedView?.id === VARIABLES_VIEW_ID) {
                view = viewService.getActiveViewWithId(VARIABLES_VIEW_ID);
                elementContext = "variables";
            }
            if (!view) {
                return;
            }
            elements = view.treeSelection.filter(e => e instanceof Expression || e instanceof Variable);
        } else if (arg instanceof Variable || arg instanceof Expression) {
            elementContext = "watch";
            elements = [arg];
        } else {
            elementContext = "variables";
            elements = variableInternalContext ? [variableInternalContext] : [];
        }
        const stackFrame = debugService.getViewModel().focusedStackFrame;
        const session = debugService.getViewModel().focusedSession;
        if (!stackFrame || !session || elements.length === 0) {
            return;
        }
        const evalContext = session.capabilities.supportsClipboardContext ? "clipboard" : elementContext;
        const toEvaluate = ( elements.map(
            element => element instanceof Variable ? (element.evaluateName || element.value) : element.name
        ));
        try {
            const evaluations = await Promise.all(( toEvaluate.map(expr => session.evaluate(expr, stackFrame.frameId, evalContext))));
            const result = ( coalesce(evaluations).map(evaluation => evaluation.body.result));
            if (result.length) {
                clipboardService.writeText(result.join("\n"));
            }
        } catch (e) {
            const result = ( elements.map(element => element.value));
            clipboardService.writeText(result.join("\n"));
        }
    }
});
const VIEW_MEMORY_ID = "workbench.debug.viewlet.action.viewMemory";
const HEX_EDITOR_EXTENSION_ID = "ms-vscode.hexeditor";
const HEX_EDITOR_EDITOR_ID = "hexEditor.hexedit";
CommandsRegistry.registerCommand({
    id: VIEW_MEMORY_ID,
    handler: async (accessor, arg, ctx) => {
        const debugService = accessor.get(IDebugService);
        let sessionId;
        let memoryReference;
        if ("sessionId" in arg) {
            if (!arg.sessionId || !arg.variable.memoryReference) {
                return;
            }
            sessionId = arg.sessionId;
            memoryReference = arg.variable.memoryReference;
        } else {
            if (!arg.memoryReference) {
                return;
            }
            const focused = debugService.getViewModel().focusedSession;
            if (!focused) {
                return;
            }
            sessionId = focused.getId();
            memoryReference = arg.memoryReference;
        }
        const extensionsWorkbenchService = accessor.get(IExtensionsWorkbenchService);
        const editorService = accessor.get(IEditorService);
        const notificationService = accessor.get(INotificationService);
        const extensionService = accessor.get(IExtensionService);
        const telemetryService = accessor.get(ITelemetryService);
        const ext = await extensionService.getExtension(HEX_EDITOR_EXTENSION_ID);
        if (ext || (await tryInstallHexEditor(extensionsWorkbenchService, notificationService))) {
            telemetryService.publicLog("debug/didViewMemory", {
                debugType: debugService.getModel().getSession(sessionId)?.configuration.type
            });
            await editorService.openEditor({
                resource: getUriForDebugMemory(sessionId, memoryReference),
                options: {
                    revealIfOpened: true,
                    override: HEX_EDITOR_EDITOR_ID
                }
            }, SIDE_GROUP);
        }
    }
});
async function tryInstallHexEditor(extensionsWorkbenchService, notificationService) {
    try {
        await extensionsWorkbenchService.install(HEX_EDITOR_EXTENSION_ID, {
            justification: ( localize(9354, "Inspecting binary data requires this extension.")),
            enable: true
        }, ProgressLocation.Notification);
        return true;
    } catch (error) {
        notificationService.error(error);
        return false;
    }
}
CommandsRegistry.registerCommand({
    metadata: {
        description: COPY_EVALUATE_PATH_LABEL
    },
    id: COPY_EVALUATE_PATH_ID,
    handler: async (accessor, context) => {
        const clipboardService = accessor.get(IClipboardService);
        if (context instanceof Variable) {
            await clipboardService.writeText(context.evaluateName);
        } else {
            await clipboardService.writeText(context.variable.evaluateName);
        }
    }
});
CommandsRegistry.registerCommand({
    metadata: {
        description: ADD_TO_WATCH_LABEL
    },
    id: ADD_TO_WATCH_ID,
    handler: async (accessor, context) => {
        const debugService = accessor.get(IDebugService);
        debugService.addWatchExpression(context.variable.evaluateName);
    }
});
registerAction2(class extends ViewAction {
    constructor() {
        super({
            id: "variables.collapse",
            viewId: VARIABLES_VIEW_ID,
            title: ( localize(9355, "Collapse All")),
            f1: false,
            icon: Codicon.collapseAll,
            menu: {
                id: MenuId.ViewTitle,
                group: "navigation",
                when: ( ContextKeyExpr.equals("view", VARIABLES_VIEW_ID))
            }
        });
    }
    runInView(_accessor, view) {
        view.collapseAll();
    }
});

export { SET_VARIABLE_ID, VIEW_MEMORY_ID, VariablesRenderer, VariablesView, VisualizedVariableRenderer, openContextMenuForVariableTreeElement };
