/**
 * Copyright (c) 2020-present, Goldman Sachs
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
import { action, computed, flow, flowResult, makeObservable, observable, } from 'mobx';
import { ExplorerTreeState } from './ExplorerTreeState.js';
import { ACTIVITY_MODE, PANEL_MODE, GRAPH_EDITOR_MODE, EDITOR_MODE, } from './EditorConfig.js';
import { EditorGraphState, GraphBuilderStatus, } from './EditorGraphState.js';
import { ChangeDetectionState } from './ChangeDetectionState.js';
import { NewElementState } from './NewElementState.js';
import { WorkspaceUpdaterState } from './sidebar-state/WorkspaceUpdaterState.js';
import { ProjectOverviewState } from './sidebar-state/ProjectOverviewState.js';
import { WorkspaceReviewState } from './sidebar-state/WorkspaceReviewState.js';
import { FormLocalChangesState, } from './sidebar-state/LocalChangesState.js';
import { WorkspaceWorkflowManagerState } from './sidebar-state/WorkflowManagerState.js';
import { LogEvent, isNonNullable, assertErrorThrown, guaranteeNonNullable, UnsupportedOperationError, ActionState, AssertionError, guaranteeType, returnUndefOnError, } from '@finos/legend-shared';
import { EditorSDLCState } from './EditorSDLCState.js';
import { ModelImporterState } from './editor-state/ModelImporterState.js';
import { ProjectConfigurationEditorState } from './editor-state/project-configuration-editor-state/ProjectConfigurationEditorState.js';
import { DevToolPanelState, payloadDebugger, } from './panel-group/DevToolPanelState.js';
import { generateEditorRoute, generateSetupRoute, generateViewProjectRoute, LEGEND_STUDIO_QUERY_PARAMS, } from '../../__lib__/LegendStudioNavigation.js';
import { PanelDisplayState } from '@finos/legend-art';
import { ProjectConfiguration, WorkspaceType, } from '@finos/legend-server-sdlc';
import { GraphManagerState, GRAPH_MANAGER_EVENT } from '@finos/legend-graph';
import { ActionAlertActionType, ActionAlertType, APPLICATION_EVENT, DEFAULT_TAB_SIZE, } from '@finos/legend-application';
import { LEGEND_STUDIO_APP_EVENT } from '../../__lib__/LegendStudioEvent.js';
import { LegendStudioUserDataHelper } from '../../__lib__/LegendStudioUserDataHelper.js';
import { StandardEditorMode } from './StandardEditorMode.js';
import { WorkspaceUpdateConflictResolutionState } from './sidebar-state/WorkspaceUpdateConflictResolutionState.js';
import { PACKAGEABLE_ELEMENT_TYPE, PACKAGEABLE_ELEMENT_GROUP_BY_CATEGORY, } from './utils/ModelClassifierUtils.js';
import { GlobalTestRunnerState } from './sidebar-state/testable/GlobalTestRunnerState.js';
import { EmbeddedQueryBuilderState } from './EmbeddedQueryBuilderState.js';
import { LEGEND_STUDIO_COMMAND_KEY } from '../../__lib__/LegendStudioCommand.js';
import { EditorTabManagerState } from './EditorTabManagerState.js';
import { GraphEditFormModeState } from './GraphEditFormModeState.js';
import { GraphEditGrammarModeState } from './GraphEditGrammarModeState.js';
import { GlobalBulkServiceRegistrationState } from './sidebar-state/BulkServiceRegistrationState.js';
import { StudioSQLPlaygroundPanelState } from './panel-group/StudioSQLPlaygroundPanelState.js';
import { LegendSQLStudioPlaygroundState } from './LegendSQLStudioPlaygroundState.js';
import { GlobalEndToEndWorkflowState } from './sidebar-state/end-to-end-workflow/GlobalEndToEndFlowState.js';
import { SHOWCASE_PANEL_LOCAL_STORAGE, toggleShowcasePanel, } from '../../components/editor/ShowcaseSideBar.js';
import { GraphEditLazyGrammarModeState, LazyTextEditorStore, } from '../lazy-text-editor/LazyTextEditorStore.js';
import { EditorInitialConfiguration } from './editor-state/element-editor-state/ElementEditorInitialConfiguration.js';
import { LakehouseIngestionManager } from '@finos/legend-server-lakehouse';
import { DevMetadataState } from './sidebar-state/dev-metadata/DevMetadataState.js';
export class EditorExtensionState {
    /**
     * This helps to better type-check for this empty abtract type
     * See https://github.com/finos/legend-studio/blob/master/docs/technical/typescript-usage.md#understand-typescript-structual-type-system
     */
    _$nominalTypeBrand;
}
export class EditorStore {
    applicationStore;
    sdlcServerClient;
    depotServerClient;
    ingestionManager;
    pluginManager;
    /**
     * This is a mechanism to have the store holds references to extension states
     * so that we can refer back to these states when needed or do cross-extensions
     * operations
     */
    extensionStates = [];
    initState = ActionState.create();
    initialEntityPath;
    editorConfig;
    editorMode;
    // NOTE: once we clear up the editor store to make modes more separated
    // we should remove these sets of functions. They are basically hacks to
    // ensure hiding parts of the UI based on the editing mode.
    // Instead, we will gradually move these `boolean` flags into `EditorMode`
    // See https://github.com/finos/legend-studio/issues/317
    mode = EDITOR_MODE.STANDARD;
    // SDLC
    sdlcState;
    changeDetectionState;
    // TODO: make EditorGraphState extend GraphMangerState and merge the state together for Studio
    graphState;
    graphManagerState;
    graphEditorMode;
    // sidebar and panel
    explorerTreeState;
    projectOverviewState;
    workspaceWorkflowManagerState;
    globalTestRunnerState;
    workspaceUpdaterState;
    workspaceReviewState;
    localChangesState;
    conflictResolutionState;
    globalBulkServiceRegistrationState;
    globalEndToEndWorkflowState;
    devToolState;
    devMetadataState;
    studioSqlPlaygroundState;
    legendSQLStudioPlaygroundState;
    modelImporterState;
    projectConfigurationEditorState;
    embeddedQueryBuilderState;
    embeddedDataCubeViewerState;
    newElementState;
    /**
     * Since we want to share element generation state across all element in the editor, we will create 1 element generate state
     * per file generation configuration type.
     */
    elementGenerationStates = [];
    showSearchElementCommand = false;
    quickInputState;
    activePanelMode = PANEL_MODE.CONSOLE;
    panelGroupDisplayState = new PanelDisplayState({
        initial: 0,
        default: 300,
        snap: 100,
    });
    activeActivity = ACTIVITY_MODE.EXPLORER;
    sideBarDisplayState = new PanelDisplayState({
        initial: 300,
        default: 300,
        snap: 150,
    });
    showcasePanelDisplayState;
    showcaseDefaultSize = 500;
    tabManagerState = new EditorTabManagerState(this);
    supportedElementTypesWithCategory;
    lazyTextEditorStore = new LazyTextEditorStore(this);
    constructor(applicationStore, sdlcServerClient, depotServerClient) {
        makeObservable(this, {
            editorMode: observable,
            mode: observable,
            activePanelMode: observable,
            activeActivity: observable,
            graphEditorMode: observable,
            showSearchElementCommand: observable,
            quickInputState: observable,
            lazyTextEditorStore: observable,
            isInViewerMode: computed,
            disableGraphEditing: computed,
            isInConflictResolutionMode: computed,
            isInitialized: computed,
            setEditorMode: action,
            setMode: action,
            setActivePanelMode: action,
            cleanUp: action,
            reset: action,
            setActiveActivity: action,
            setShowSearchElementCommand: action,
            setQuickInputState: action,
            initialize: flow,
            initMode: flow,
            initStandardMode: flow,
            initializeLazyTextMode: flow,
            initConflictResolutionMode: flow,
            buildGraph: flow,
            toggleTextMode: flow,
            switchModes: flow,
            embeddedDataCubeViewerState: observable,
            setEmbeddedDataCubeViewerState: action,
        });
        this.applicationStore = applicationStore;
        this.sdlcServerClient = sdlcServerClient;
        this.depotServerClient = depotServerClient;
        this.pluginManager = applicationStore.pluginManager;
        this.editorMode = new StandardEditorMode(this);
        this.sdlcState = new EditorSDLCState(this);
        this.graphState = new EditorGraphState(this);
        this.graphManagerState = new GraphManagerState(applicationStore.pluginManager, applicationStore.logService);
        this.graphEditorMode = new GraphEditFormModeState(this);
        this.changeDetectionState = new ChangeDetectionState(this, this.graphState);
        this.devToolState = new DevToolPanelState(this);
        this.devMetadataState = new DevMetadataState(this);
        this.studioSqlPlaygroundState = new StudioSQLPlaygroundPanelState(this);
        this.legendSQLStudioPlaygroundState = new LegendSQLStudioPlaygroundState(this);
        this.embeddedQueryBuilderState = new EmbeddedQueryBuilderState(this);
        // side bar panels
        this.explorerTreeState = new ExplorerTreeState(this);
        this.projectOverviewState = new ProjectOverviewState(this, this.sdlcState);
        this.globalTestRunnerState = new GlobalTestRunnerState(this, this.sdlcState);
        this.globalEndToEndWorkflowState = new GlobalEndToEndWorkflowState(this);
        this.workspaceWorkflowManagerState = new WorkspaceWorkflowManagerState(this, this.sdlcState);
        this.workspaceUpdaterState = new WorkspaceUpdaterState(this, this.sdlcState);
        this.workspaceReviewState = new WorkspaceReviewState(this, this.sdlcState);
        this.localChangesState = new FormLocalChangesState(this, this.sdlcState);
        this.conflictResolutionState = new WorkspaceUpdateConflictResolutionState(this, this.sdlcState);
        this.newElementState = new NewElementState(this);
        this.globalBulkServiceRegistrationState =
            new GlobalBulkServiceRegistrationState(this, this.sdlcState);
        // special (singleton) editors
        this.modelImporterState = new ModelImporterState(this);
        this.projectConfigurationEditorState = new ProjectConfigurationEditorState(this, this.sdlcState);
        // ingestion
        const ingestionConifg = applicationStore.config.options.ingestDeploymentConfig;
        if (ingestionConifg) {
            this.ingestionManager = new LakehouseIngestionManager(ingestionConifg.discoveryUrl, ingestionConifg.deployment.defaultServer, ingestionConifg.deployment.useDefaultServer, this.applicationStore.tracerService);
        }
        // extensions
        this.extensionStates = this.pluginManager
            .getApplicationPlugins()
            .flatMap((plugin) => plugin.getExtraEditorExtensionStateBuilders?.() ?? [])
            .map((creator) => creator(this))
            .filter(isNonNullable);
        this.supportedElementTypesWithCategory =
            this.getSupportedElementTypesWithCategory();
        this.showcasePanelDisplayState = new PanelDisplayState({
            initial: this.showcaseInitialSize,
            default: this.showcaseDefaultSize,
            snap: 150,
        });
    }
    get showcaseInitialSize() {
        const showcasesSavedAsOpen = this.applicationStore.userDataService.getBooleanValue(SHOWCASE_PANEL_LOCAL_STORAGE.PANEL_STATE_KEY);
        const showcaseEnabled = this.applicationStore.config.showcaseServerUrl;
        if (showcaseEnabled &&
            (showcasesSavedAsOpen || showcasesSavedAsOpen === undefined)) {
            return this.showcaseDefaultSize;
        }
        else {
            return 0;
        }
    }
    get isInitialized() {
        if (this.isInViewerMode) {
            return (this.editorMode.isInitialized &&
                this.graphManagerState.systemBuildState.hasSucceeded);
        }
        else {
            return (Boolean(this.sdlcState.currentProject &&
                this.sdlcState.currentWorkspace &&
                this.sdlcState.currentRevision &&
                this.sdlcState.remoteWorkspaceRevision) && this.graphManagerState.systemBuildState.hasSucceeded);
        }
    }
    get isInViewerMode() {
        return this.mode === EDITOR_MODE.VIEWER;
    }
    get disableGraphEditing() {
        return this.isInViewerMode && this.editorMode.disableEditing;
    }
    get isInConflictResolutionMode() {
        return this.mode === EDITOR_MODE.CONFLICT_RESOLUTION;
    }
    setEditorMode(val) {
        this.editorMode = val;
    }
    setMode(val) {
        this.mode = val;
    }
    setShowSearchElementCommand(val) {
        this.showSearchElementCommand = val;
    }
    setEmbeddedDataCubeViewerState(val) {
        this.embeddedDataCubeViewerState = val;
    }
    setQuickInputState(val) {
        this.quickInputState = val;
    }
    cleanUp() {
        // dismiss all the alerts as these are parts of application, if we don't do this, we might
        // end up blocking other parts of the app
        // e.g. trying going to an unknown workspace, we will be redirected to the home page
        // but the blocking alert for not-found workspace will still block the app
        this.applicationStore.alertService.setBlockingAlert(undefined);
        this.applicationStore.alertService.setActionAlertInfo(undefined);
        // stop change detection to avoid memory-leak
        this.changeDetectionState.stop();
    }
    /**
     * TODO?: we should really think of how we could simplify the trigger condition below
     * after we refactor editor modes
     *
     * See https://github.com/finos/legend-studio/issues/317
     */
    createEditorCommandTrigger(additionalChecker) {
        return () => 
        // we don't want to leak any hotkeys when we have embedded query builder open
        // TODO?: we probably should come up with a more generic mechanism for this
        !this.embeddedQueryBuilderState.queryBuilderState &&
            (!additionalChecker || additionalChecker());
    }
    registerCommands() {
        this.applicationStore.commandService.registerCommand({
            key: LEGEND_STUDIO_COMMAND_KEY.COMPILE,
            trigger: this.createEditorCommandTrigger(() => this.isInitialized &&
                (!this.isInConflictResolutionMode ||
                    this.conflictResolutionState.hasResolvedAllConflicts)),
            action: () => {
                flowResult(this.graphEditorMode.globalCompile()).catch(this.applicationStore.alertUnhandledError);
            },
        });
        this.applicationStore.commandService.registerCommand({
            key: LEGEND_STUDIO_COMMAND_KEY.GENERATE,
            trigger: this.createEditorCommandTrigger(() => this.isInitialized &&
                (!this.isInConflictResolutionMode ||
                    this.conflictResolutionState.hasResolvedAllConflicts)),
            action: () => {
                flowResult(this.graphState.graphGenerationState.globalGenerate()).catch(this.applicationStore.alertUnhandledError);
            },
        });
        this.applicationStore.commandService.registerCommand({
            key: LEGEND_STUDIO_COMMAND_KEY.CREATE_ELEMENT,
            trigger: this.createEditorCommandTrigger(() => !this.isInViewerMode),
            action: () => this.newElementState.openModal(),
        });
        this.applicationStore.commandService.registerCommand({
            key: LEGEND_STUDIO_COMMAND_KEY.SEARCH_ELEMENT,
            trigger: this.createEditorCommandTrigger(),
            action: () => this.setShowSearchElementCommand(!this.showSearchElementCommand),
        });
        this.applicationStore.commandService.registerCommand({
            key: LEGEND_STUDIO_COMMAND_KEY.TOGGLE_TEXT_MODE,
            trigger: this.createEditorCommandTrigger(() => this.isInitialized &&
                (!this.isInConflictResolutionMode ||
                    this.conflictResolutionState.hasResolvedAllConflicts)),
            action: () => {
                flowResult(this.toggleTextMode()).catch(this.applicationStore.alertUnhandledError);
            },
        });
        this.applicationStore.commandService.registerCommand({
            key: LEGEND_STUDIO_COMMAND_KEY.OPEN_SHOWCASES,
            trigger: this.createEditorCommandTrigger(() => this.isInitialized &&
                (!this.isInConflictResolutionMode ||
                    this.conflictResolutionState.hasResolvedAllConflicts)),
            action: () => {
                toggleShowcasePanel(this);
            },
        });
        this.applicationStore.commandService.registerCommand({
            key: LEGEND_STUDIO_COMMAND_KEY.TOGGLE_MODEL_LOADER,
            trigger: this.createEditorCommandTrigger(() => !this.isInViewerMode),
            action: () => this.tabManagerState.openTab(this.modelImporterState),
        });
        this.applicationStore.commandService.registerCommand({
            key: LEGEND_STUDIO_COMMAND_KEY.SYNC_WITH_WORKSPACE,
            trigger: this.createEditorCommandTrigger(() => !this.isInViewerMode),
            action: () => {
                flowResult(this.localChangesState.pushLocalChanges()).catch(this.applicationStore.alertUnhandledError);
            },
        });
        this.applicationStore.commandService.registerCommand({
            key: LEGEND_STUDIO_COMMAND_KEY.TOGGLE_PANEL_GROUP,
            trigger: this.createEditorCommandTrigger(() => !this.isInViewerMode),
            action: () => this.panelGroupDisplayState.toggle(),
        });
        this.applicationStore.commandService.registerCommand({
            key: LEGEND_STUDIO_COMMAND_KEY.TOGGLE_SIDEBAR_EXPLORER,
            trigger: this.createEditorCommandTrigger(),
            action: () => this.setActiveActivity(ACTIVITY_MODE.EXPLORER),
        });
        this.applicationStore.commandService.registerCommand({
            key: LEGEND_STUDIO_COMMAND_KEY.TOGGLE_SIDEBAR_LOCAL_CHANGES,
            trigger: this.createEditorCommandTrigger(() => !this.isInViewerMode),
            action: () => this.setActiveActivity(ACTIVITY_MODE.LOCAL_CHANGES),
        });
        this.applicationStore.commandService.registerCommand({
            key: LEGEND_STUDIO_COMMAND_KEY.TOGGLE_SIDEBAR_WORKSPACE_REVIEW,
            trigger: this.createEditorCommandTrigger(() => !this.isInViewerMode),
            action: () => this.setActiveActivity(ACTIVITY_MODE.WORKSPACE_REVIEW),
        });
        this.applicationStore.commandService.registerCommand({
            key: LEGEND_STUDIO_COMMAND_KEY.TOGGLE_SIDEBAR_WORKSPACE_UPDATER,
            trigger: this.createEditorCommandTrigger(() => !this.isInViewerMode),
            action: () => this.setActiveActivity(ACTIVITY_MODE.WORKSPACE_UPDATER),
        });
    }
    deregisterCommands() {
        [
            LEGEND_STUDIO_COMMAND_KEY.SYNC_WITH_WORKSPACE,
            LEGEND_STUDIO_COMMAND_KEY.CREATE_ELEMENT,
            LEGEND_STUDIO_COMMAND_KEY.SEARCH_ELEMENT,
            LEGEND_STUDIO_COMMAND_KEY.TOGGLE_TEXT_MODE,
            LEGEND_STUDIO_COMMAND_KEY.GENERATE,
            LEGEND_STUDIO_COMMAND_KEY.COMPILE,
            LEGEND_STUDIO_COMMAND_KEY.TOGGLE_PANEL_GROUP,
            LEGEND_STUDIO_COMMAND_KEY.TOGGLE_MODEL_LOADER,
            LEGEND_STUDIO_COMMAND_KEY.TOGGLE_SIDEBAR_EXPLORER,
            LEGEND_STUDIO_COMMAND_KEY.TOGGLE_SIDEBAR_LOCAL_CHANGES,
            LEGEND_STUDIO_COMMAND_KEY.TOGGLE_SIDEBAR_WORKSPACE_REVIEW,
            LEGEND_STUDIO_COMMAND_KEY.TOGGLE_SIDEBAR_WORKSPACE_UPDATER,
        ].forEach((key) => this.applicationStore.commandService.deregisterCommand(key));
    }
    reset() {
        this.tabManagerState.closeAllTabs();
        this.projectConfigurationEditorState = new ProjectConfigurationEditorState(this, this.sdlcState);
        this.explorerTreeState = new ExplorerTreeState(this);
    }
    deCodeStudioQueryParams(studioParams) {
        if (this.editorConfig) {
            // If editor config is already set, we do not decode again
            return;
        }
        if (!studioParams) {
            // If studio params are not provided, we do not decode
            return;
        }
        const editorConfig = studioParams[LEGEND_STUDIO_QUERY_PARAMS.EDITOR_CONFIG];
        if (!editorConfig) {
            return;
        }
        const _config = returnUndefOnError(() => EditorInitialConfiguration.serialization.fromJson(JSON.parse(atob(editorConfig))));
        const config = guaranteeNonNullable(_config, `error reading and serializing config ${editorConfig}`);
        this.editorConfig = config;
    }
    internalizeEntityPath(params, studioParams) {
        const { projectId, entityPath } = params;
        const workspaceType = params.groupWorkspaceId
            ? WorkspaceType.GROUP
            : WorkspaceType.USER;
        const workspaceId = guaranteeNonNullable(params.groupWorkspaceId ?? params.workspaceId, `Workspace/group workspace ID is not provided`);
        if (entityPath) {
            this.initialEntityPath = entityPath;
            this.deCodeStudioQueryParams(studioParams);
            this.applicationStore.navigationService.navigator.updateCurrentLocation(generateEditorRoute(guaranteeNonNullable(projectId), params.patchReleaseVersionId, workspaceId, workspaceType));
        }
    }
    /**
     * This is the entry of the app logic where the initialization of editor states happens
     * Here, we ensure the order of calls after checking existence of current project and workspace
     * If either of them does not exist, we cannot proceed.
     */
    *initialize(projectId, patchReleaseVersionId, workspaceId, workspaceType, studioParams) {
        if (!this.initState.isInInitialState) {
            /**
             * Since React `fast-refresh` will sometimes cause `Editor` to rerender, this method will be called again
             * as all hooks are recalled, as such, ONLY IN DEVELOPMENT mode we allow this to not fail-fast
             * we also have to `undo` some of what the `cleanUp` does to this store as the cleanup part of all hooks
             * will be triggered as well
             */
            // eslint-disable-next-line no-process-env
            if (process.env.NODE_ENV === 'development') {
                this.applicationStore.logService.debug(LogEvent.create(APPLICATION_EVENT.DEBUG), `Fast-refreshing the app - undoing cleanUp() and preventing initialize() recall in editor store...`);
                this.changeDetectionState.start();
                return;
            }
            // eslint-disable-next-line no-process-env
            if (process.env.NODE_ENV === 'production') {
                // TEMPORARY suppress until we investigate
                this.applicationStore.logService.debug(LogEvent.create(APPLICATION_EVENT.DEBUG), 'Editor store is re-initialized');
            }
            else {
                this.applicationStore.logService.debug(LogEvent.create(APPLICATION_EVENT.DEBUG), 'Editor store is re-initialized');
            }
            return;
        }
        this.initState.inProgress();
        this.deCodeStudioQueryParams(studioParams);
        // TODO: when we genericize the way to initialize an application page
        this.applicationStore.assistantService.setIsHidden(false);
        const onLeave = (hasBuildSucceeded) => {
            this.initState.complete(hasBuildSucceeded);
            this.initState.setMessage(undefined);
        };
        this.initState.setMessage(`Setting up workspace...`);
        yield flowResult(this.sdlcState.fetchCurrentProject(projectId, {
            suppressNotification: true,
        }));
        if (!this.sdlcState.currentProject) {
            // The project the user navigated to doesn't exist (or isn't accessible).
            // Drop it from the recents cache so we don't keep offering a dead link.
            LegendStudioUserDataHelper.workspaceSetup_removeRecentProject(this.applicationStore.userDataService, projectId);
            // If the project is not found or the user does not have access to it,
            // we will not automatically redirect them to the setup page as they will lose the URL
            // instead, we give them the option to:
            // - reload the page (in case they later gain access)
            // - back to the setup page
            this.applicationStore.alertService.setActionAlertInfo({
                message: `Project not found or inaccessible`,
                prompt: 'Please check that the project exists and request access to it',
                type: ActionAlertType.STANDARD,
                actions: [
                    {
                        label: 'Reload application',
                        default: true,
                        type: ActionAlertActionType.STANDARD,
                        handler: () => {
                            this.applicationStore.navigationService.navigator.reload();
                        },
                    },
                    {
                        label: 'Back to workspace setup',
                        type: ActionAlertActionType.STANDARD,
                        handler: () => {
                            this.applicationStore.navigationService.navigator.goToLocation(generateSetupRoute(undefined, undefined));
                        },
                    },
                ],
            });
            onLeave(false);
            return;
        }
        yield flowResult(this.sdlcState.fetchCurrentPatch(projectId, patchReleaseVersionId, {
            suppressNotification: true,
        }));
        yield flowResult(this.sdlcState.fetchCurrentWorkspace(projectId, patchReleaseVersionId, workspaceId, workspaceType, {
            suppressNotification: true,
        }));
        if (!this.sdlcState.currentWorkspace) {
            // The workspace the user navigated to doesn't exist anymore. Drop
            // the matching entry from the recents cache (no-op for patch
            // workspaces, which are never cached in the first place).
            if (patchReleaseVersionId === undefined) {
                LegendStudioUserDataHelper.workspaceSetup_removeRecentWorkspace(this.applicationStore.userDataService, { projectId, workspaceId, workspaceType });
            }
            // If the workspace is not found,
            // we will not automatically redirect the user to the setup page as they will lose the URL
            // instead, we give them the option to:
            // - create the workspace
            // - view project
            // - back to the setup page
            const createWorkspaceAndRelaunch = async () => {
                try {
                    this.applicationStore.alertService.setBlockingAlert({
                        message: 'Creating workspace...',
                        prompt: 'Please do not close the application',
                    });
                    const workspace = await this.sdlcServerClient.createWorkspace(projectId, patchReleaseVersionId, workspaceId, workspaceType);
                    this.applicationStore.alertService.setBlockingAlert(undefined);
                    this.applicationStore.notificationService.notifySuccess(`Workspace '${workspace.workspaceId}' is succesfully created. Reloading application...`);
                    this.applicationStore.navigationService.navigator.reload();
                }
                catch (error) {
                    assertErrorThrown(error);
                    this.applicationStore.logService.error(LogEvent.create(LEGEND_STUDIO_APP_EVENT.WORKSPACE_SETUP_FAILURE), error);
                    this.applicationStore.notificationService.notifyError(error);
                }
            };
            this.applicationStore.alertService.setActionAlertInfo({
                message: 'Workspace not found',
                prompt: `Please note that you can check out the project in viewer mode. Workspace is only required if you need to work on the project.`,
                type: ActionAlertType.STANDARD,
                actions: [
                    {
                        label: 'View project',
                        default: true,
                        type: ActionAlertActionType.STANDARD,
                        handler: () => {
                            this.applicationStore.navigationService.navigator.goToLocation(generateViewProjectRoute(projectId));
                        },
                    },
                    {
                        label: 'Create workspace',
                        type: ActionAlertActionType.STANDARD,
                        handler: () => {
                            createWorkspaceAndRelaunch().catch(this.applicationStore.alertUnhandledError);
                        },
                    },
                    {
                        label: 'Back to workspace setup',
                        type: ActionAlertActionType.STANDARD,
                        handler: () => {
                            this.applicationStore.navigationService.navigator.goToLocation(generateSetupRoute(projectId, workspaceId, workspaceType));
                        },
                    },
                ],
            });
            onLeave(false);
            return;
        }
        // At this point both the project and the workspace have been confirmed
        // to exist on the server (the guards above bail out otherwise), so this
        // is the authoritative "the user actually opened this workspace" moment.
        // Record it in the recents cache so the workspace setup screen can offer
        // it instantly next time.
        // NOTE: patch-based workspaces are intentionally excluded from recents
        // (they are not surfaced in the recents UI). Sandbox projects ARE
        // included — opening one is still a meaningful "I worked here" signal,
        // and surfacing it alongside other recents gives a faster one-click
        // re-entry than waiting for the dedicated sandbox loader.
        if (this.sdlcState.currentWorkspace.source === undefined) {
            LegendStudioUserDataHelper.workspaceSetup_recordRecentProject(this.applicationStore.userDataService, {
                projectId: this.sdlcState.currentProject.projectId,
                name: this.sdlcState.currentProject.name,
            });
            LegendStudioUserDataHelper.workspaceSetup_recordRecentWorkspace(this.applicationStore.userDataService, {
                projectId: this.sdlcState.currentProject.projectId,
                workspaceId: this.sdlcState.currentWorkspace.workspaceId,
                workspaceType: this.sdlcState.currentWorkspace.workspaceType,
            });
        }
        yield Promise.all([
            this.sdlcState.fetchCurrentRevision(projectId, this.sdlcState.activeWorkspace),
            this.graphManagerState.graphManager.initialize({
                env: this.applicationStore.config.env,
                tabSize: DEFAULT_TAB_SIZE,
                clientConfig: {
                    baseUrl: this.editorConfig?.engineServerUrl ??
                        this.applicationStore.config.engineServerUrl,
                    queryBaseUrl: this.editorConfig?.engineQueryServerUrl ??
                        this.applicationStore.config.engineQueryServerUrl,
                    enableCompression: true,
                    payloadDebugger,
                },
            }, {
                tracerService: this.applicationStore.tracerService,
            }),
        ]);
        yield this.graphManagerState.initializeSystem();
        yield flowResult(this.initMode());
        onLeave(true);
    }
    *initMode() {
        switch (this.mode) {
            case EDITOR_MODE.STANDARD:
                yield flowResult(this.initStandardMode());
                return;
            case EDITOR_MODE.CONFLICT_RESOLUTION:
                yield flowResult(this.initConflictResolutionMode());
                return;
            case EDITOR_MODE.LAZY_TEXT_EDITOR:
                yield flowResult(this.initializeLazyTextMode());
                return;
            default:
                throw new UnsupportedOperationError(`Can't initialize editor for unsupported mode '${this.mode}'`);
        }
    }
    *initStandardMode() {
        const projectId = this.sdlcState.activeProject.projectId;
        const activeWorkspace = this.sdlcState.activeWorkspace;
        const projectConfiguration = (yield this.sdlcServerClient.getConfiguration(projectId, activeWorkspace));
        this.projectConfigurationEditorState.setProjectConfiguration(ProjectConfiguration.serialization.fromJson(projectConfiguration));
        // make sure we set the original project configuration to a different object
        this.projectConfigurationEditorState.setOriginalProjectConfiguration(ProjectConfiguration.serialization.fromJson(projectConfiguration));
        yield Promise.all([
            this.buildGraph(),
            this.sdlcState.checkIfWorkspaceIsOutdated(),
            this.workspaceReviewState.fetchCurrentWorkspaceReview(),
            this.workspaceUpdaterState.fetchLatestCommittedReviews(),
            this.projectConfigurationEditorState.fetchLatestProjectStructureVersion(),
            this.graphState.graphGenerationState.globalFileGenerationState.fetchAvailableFileGenerationDescriptions(),
            this.graphState.graphGenerationState.externalFormatState.fetchExternalFormatDescriptions(),
            this.graphState.fetchAvailableFunctionActivatorConfigurations(),
            this.graphState.fetchAvailableRelationalDatabseTypeConfigurations(),
            this.sdlcState.fetchProjectVersions(),
            this.sdlcState.fetchPublishedProjectVersions(),
            this.sdlcState.fetchAuthorizedActions(),
        ]);
    }
    *initializeLazyTextMode() {
        // set up
        const projectId = this.sdlcState.activeProject.projectId;
        const activeWorkspace = this.sdlcState.activeWorkspace;
        const projectConfiguration = (yield this.sdlcServerClient.getConfiguration(projectId, activeWorkspace));
        this.projectConfigurationEditorState.setProjectConfiguration(ProjectConfiguration.serialization.fromJson(projectConfiguration));
        // make sure we set the original project configuration to a different object
        this.projectConfigurationEditorState.setOriginalProjectConfiguration(ProjectConfiguration.serialization.fromJson(projectConfiguration));
        const startTime = Date.now();
        let entities;
        this.initState.setMessage(`Fetching entities...`);
        try {
            entities = (yield this.sdlcServerClient.getEntities(projectId, activeWorkspace));
            this.changeDetectionState.workspaceLocalLatestRevisionState.setEntities(entities);
            this.applicationStore.logService.info(LogEvent.create(GRAPH_MANAGER_EVENT.FETCH_GRAPH_ENTITIES__SUCCESS), Date.now() - startTime, 'ms');
        }
        catch (error) {
            assertErrorThrown(error);
            this.applicationStore.logService.error(LogEvent.create(GRAPH_MANAGER_EVENT.FETCH_GRAPH_ENTITIES_ERROR), Date.now() - startTime, 'ms');
            this.applicationStore.notificationService.notifyError(error);
            return;
        }
        finally {
            this.initState.setMessage(undefined);
        }
        this.initState.setMessage('Building entities hash...');
        yield flowResult(this.changeDetectionState.workspaceLocalLatestRevisionState.buildEntityHashesIndex(entities, LogEvent.create(LEGEND_STUDIO_APP_EVENT.CHANGE_DETECTION_BUILD_LOCAL_HASHES_INDEX__SUCCESS)));
        this.initState.setMessage('Building strict lazy graph...');
        (yield flowResult(this.graphState.buildGraphForLazyText()));
        this.graphManagerState.graphBuildState.sync(ActionState.create().pass());
        this.graphManagerState.generationsBuildState.sync(ActionState.create().pass());
        this.initState.setMessage(undefined);
        // switch to text mode
        const graphEditorMode = new GraphEditLazyGrammarModeState(this);
        try {
            const editorGrammar = (yield this.graphManagerState.graphManager.entitiesToPureCode(this.changeDetectionState.workspaceLocalLatestRevisionState.entities, { pretty: true }));
            yield flowResult(graphEditorMode.grammarTextEditorState.setGraphGrammarText(editorGrammar));
            this.graphEditorMode = graphEditorMode;
            yield flowResult(this.graphEditorMode.initialize({
                useStoredEntities: true,
            }));
        }
        catch (error) {
            assertErrorThrown(error);
            this.applicationStore.notificationService.notifyWarning(`Can't initialize strict text mode. Issue converting entities to grammar: ${error.message}`);
            this.applicationStore.alertService.setBlockingAlert(undefined);
            return;
        }
    }
    *initConflictResolutionMode() {
        yield flowResult(this.conflictResolutionState.initProjectConfigurationInConflictResolutionMode());
        this.applicationStore.alertService.setActionAlertInfo({
            message: 'Failed to update workspace.',
            prompt: 'You can discard all of your changes or review them, resolve all merge conflicts and fix any potential compilation issues as well as test failures',
            type: ActionAlertType.CAUTION,
            actions: [
                {
                    label: 'Discard your changes',
                    type: ActionAlertActionType.PROCEED_WITH_CAUTION,
                    handler: () => {
                        this.setActiveActivity(ACTIVITY_MODE.CONFLICT_RESOLUTION);
                        flowResult(this.conflictResolutionState.discardConflictResolutionChanges()).catch((error) => this.applicationStore.alertUnhandledError(error));
                    },
                },
                {
                    label: 'Resolve merge conflicts',
                    default: true,
                    type: ActionAlertActionType.STANDARD,
                },
            ],
        });
        yield Promise.all([
            this.conflictResolutionState.initialize(),
            this.sdlcState.checkIfWorkspaceIsOutdated(),
            this.projectConfigurationEditorState.fetchLatestProjectStructureVersion(),
            this.graphState.graphGenerationState.globalFileGenerationState.fetchAvailableFileGenerationDescriptions(),
            this.graphState.graphGenerationState.externalFormatState.fetchExternalFormatDescriptions(),
            this.graphState.fetchAvailableFunctionActivatorConfigurations(),
            this.graphState.fetchAvailableRelationalDatabseTypeConfigurations(),
            this.sdlcState.fetchProjectVersions(),
            this.sdlcState.fetchPublishedProjectVersions(),
            this.sdlcState.fetchAuthorizedActions(),
        ]);
    }
    *buildGraph(graphEntities) {
        const startTime = Date.now();
        let entities;
        this.initState.setMessage(`Fetching entities...`);
        try {
            // fetch workspace entities and config at the same time
            const projectId = this.sdlcState.activeProject.projectId;
            const activeWorkspace = this.sdlcState.activeWorkspace;
            entities = (yield this.sdlcServerClient.getEntities(projectId, activeWorkspace));
            this.changeDetectionState.workspaceLocalLatestRevisionState.setEntities(entities);
            this.applicationStore.logService.info(LogEvent.create(GRAPH_MANAGER_EVENT.FETCH_GRAPH_ENTITIES__SUCCESS), Date.now() - startTime, 'ms');
        }
        catch (error) {
            assertErrorThrown(error);
            this.applicationStore.logService.error(LogEvent.create(GRAPH_MANAGER_EVENT.FETCH_GRAPH_ENTITIES_ERROR), Date.now() - startTime, 'ms');
            this.applicationStore.notificationService.notifyError(error);
            return;
        }
        finally {
            this.initState.setMessage(undefined);
        }
        try {
            const result = (yield flowResult(
            // NOTE: if graph entities are provided, we will use that to build the graph.
            // We use this method as a way to fully reset the application with the entities, but we still use
            // the workspace entities for hashing as those are the base entities.
            this.graphState.buildGraph(graphEntities ?? entities)));
            if (result.error) {
                if (result.status === GraphBuilderStatus.REDIRECTED_TO_TEXT_MODE) {
                    yield flowResult(this.changeDetectionState.workspaceLocalLatestRevisionState.buildEntityHashesIndex(entities, LogEvent.create(LEGEND_STUDIO_APP_EVENT.CHANGE_DETECTION_BUILD_LOCAL_HASHES_INDEX__SUCCESS)));
                }
                return;
            }
            this.initState.setMessage(`Starting change detection engine...`);
            // build explorer tree
            this.explorerTreeState.buildImmutableModelTrees();
            this.explorerTreeState.build();
            // open element if provided an element path
            if (this.graphManagerState.graphBuildState.hasSucceeded &&
                this.explorerTreeState.buildState.hasCompleted &&
                this.initialEntityPath) {
                try {
                    this.graphEditorMode.openElement(this.graphManagerState.graph.getElement(this.initialEntityPath), this.editorConfig);
                }
                catch {
                    const elementPath = this.initialEntityPath;
                    this.initialEntityPath = undefined;
                    throw new AssertionError(`Can't find element with path '${elementPath}'`);
                }
            }
            // ======= (RE)START CHANGE DETECTION =======
            this.changeDetectionState.stop();
            yield flowResult(this.changeDetectionState.observeGraph());
            yield Promise.all([
                this.changeDetectionState.preComputeGraphElementHashes(), // for local changes detection
                this.changeDetectionState.workspaceLocalLatestRevisionState.buildEntityHashesIndex(entities, LogEvent.create(LEGEND_STUDIO_APP_EVENT.CHANGE_DETECTION_BUILD_LOCAL_HASHES_INDEX__SUCCESS)),
                this.sdlcState.buildWorkspaceBaseRevisionEntityHashesIndex(),
                this.sdlcState.buildProjectLatestRevisionEntityHashesIndex(),
            ]);
            this.changeDetectionState.start();
            yield Promise.all([
                this.changeDetectionState.computeAggregatedWorkspaceChanges(true),
                this.changeDetectionState.computeAggregatedProjectLatestChanges(true),
            ]);
            this.applicationStore.logService.info(LogEvent.create(LEGEND_STUDIO_APP_EVENT.CHANGE_DETECTION_RESTART__SUCCESS), '[ASNYC]');
            // ======= FINISHED (RE)START CHANGE DETECTION =======
        }
        catch (error) {
            assertErrorThrown(error);
            this.applicationStore.logService.error(LogEvent.create(GRAPH_MANAGER_EVENT.GRAPH_BUILDER_FAILURE), error);
            // since errors have been handled accordingly, we don't need to do anything here
            return;
        }
        finally {
            this.initState.setMessage(undefined);
        }
    }
    setActiveActivity(activity, options) {
        if (!this.sideBarDisplayState.isOpen) {
            this.sideBarDisplayState.open();
        }
        else if (activity === this.activeActivity &&
            !options?.keepShowingIfMatchedCurrent) {
            this.sideBarDisplayState.close();
        }
        this.activeActivity = activity;
    }
    setActivePanelMode(val) {
        this.activePanelMode = val;
    }
    *toggleTextMode() {
        if (this.graphState.checkIfApplicationUpdateOperationIsRunning()) {
            return;
        }
        if (this.graphEditorMode.disableLeaveMode) {
            this.graphEditorMode.onLeave();
            return;
        }
        if (this.graphEditorMode instanceof GraphEditFormModeState) {
            this.applicationStore.alertService.setBlockingAlert({
                message: 'Switching to text mode...',
                showLoading: true,
            });
            yield flowResult(this.switchModes(GRAPH_EDITOR_MODE.GRAMMAR_TEXT));
        }
        else if (this.graphEditorMode instanceof GraphEditGrammarModeState) {
            yield flowResult(this.switchModes(GRAPH_EDITOR_MODE.FORM));
        }
        else {
            throw new UnsupportedOperationError('Editor only support form mode and text mode at the moment');
        }
    }
    getSupportedElementTypesWithCategory() {
        const elementTypesWithCategoryMap = new Map();
        Object.values(PACKAGEABLE_ELEMENT_GROUP_BY_CATEGORY).forEach((value) => {
            switch (value) {
                case PACKAGEABLE_ELEMENT_GROUP_BY_CATEGORY.MODEL: {
                    const elements = [
                        PACKAGEABLE_ELEMENT_TYPE.PACKAGE,
                        PACKAGEABLE_ELEMENT_TYPE.CLASS,
                        PACKAGEABLE_ELEMENT_TYPE.ASSOCIATION,
                        PACKAGEABLE_ELEMENT_TYPE.ENUMERATION,
                        PACKAGEABLE_ELEMENT_TYPE.PROFILE,
                        PACKAGEABLE_ELEMENT_TYPE.FUNCTION,
                        PACKAGEABLE_ELEMENT_TYPE.MEASURE,
                        PACKAGEABLE_ELEMENT_TYPE.DATA,
                    ];
                    elementTypesWithCategoryMap.set(PACKAGEABLE_ELEMENT_GROUP_BY_CATEGORY.MODEL, elements);
                    break;
                }
                case PACKAGEABLE_ELEMENT_GROUP_BY_CATEGORY.STORE: {
                    const elements = [
                        PACKAGEABLE_ELEMENT_TYPE.DATABASE,
                        PACKAGEABLE_ELEMENT_TYPE.FLAT_DATA_STORE,
                    ];
                    elementTypesWithCategoryMap.set(PACKAGEABLE_ELEMENT_GROUP_BY_CATEGORY.STORE, elements);
                    break;
                }
                case PACKAGEABLE_ELEMENT_GROUP_BY_CATEGORY.QUERY: {
                    const elements = [
                        PACKAGEABLE_ELEMENT_TYPE.CONNECTION,
                        PACKAGEABLE_ELEMENT_TYPE.RUNTIME,
                        PACKAGEABLE_ELEMENT_TYPE.MAPPING,
                        PACKAGEABLE_ELEMENT_TYPE.SERVICE,
                        PACKAGEABLE_ELEMENT_TYPE._DATA_PRODUCT,
                        this.applicationStore.config.options
                            .TEMPORARY__enableLocalConnectionBuilder
                            ? PACKAGEABLE_ELEMENT_TYPE.TEMPORARY__LOCAL_CONNECTION
                            : undefined,
                    ];
                    elementTypesWithCategoryMap.set(PACKAGEABLE_ELEMENT_GROUP_BY_CATEGORY.QUERY, elements.filter(isNonNullable));
                    break;
                }
                // for displaying categories in order
                case PACKAGEABLE_ELEMENT_GROUP_BY_CATEGORY.EXTERNAL_FORMAT: {
                    elementTypesWithCategoryMap.set(PACKAGEABLE_ELEMENT_GROUP_BY_CATEGORY.EXTERNAL_FORMAT, []);
                    break;
                }
                case PACKAGEABLE_ELEMENT_GROUP_BY_CATEGORY.GENERATION: {
                    const elements = [
                        PACKAGEABLE_ELEMENT_TYPE.FILE_GENERATION,
                        PACKAGEABLE_ELEMENT_TYPE.GENERATION_SPECIFICATION,
                    ];
                    elementTypesWithCategoryMap.set(PACKAGEABLE_ELEMENT_GROUP_BY_CATEGORY.GENERATION, elements);
                    break;
                }
                // for displaying categories in order
                case PACKAGEABLE_ELEMENT_GROUP_BY_CATEGORY.OTHER: {
                    elementTypesWithCategoryMap.set(PACKAGEABLE_ELEMENT_GROUP_BY_CATEGORY.OTHER, []);
                    break;
                }
                default:
                    break;
            }
        });
        const extensions = this.pluginManager
            .getApplicationPlugins()
            .flatMap((plugin) => plugin.getExtraSupportedElementTypesWithCategory?.() ??
            new Map());
        const elementTypesWithCategoryMapFromExtensions = new Map();
        extensions.forEach((typeCategoryMap) => {
            Array.from(typeCategoryMap.entries()).forEach((entry) => {
                const [key, value] = entry;
                elementTypesWithCategoryMapFromExtensions.set(key, elementTypesWithCategoryMapFromExtensions.get(key) === undefined
                    ? [...value]
                    : [
                        ...guaranteeNonNullable(elementTypesWithCategoryMapFromExtensions.get(key)),
                        ...value,
                    ]);
            });
        });
        // sort extensions alphabetically and insert extensions into the base elementTypesWithCategoryMap
        Array.from(elementTypesWithCategoryMapFromExtensions.entries()).forEach((entry) => {
            const [key, value] = entry;
            value.sort((a, b) => a.localeCompare(b));
            const existingValues = elementTypesWithCategoryMap.get(key);
            elementTypesWithCategoryMap.set(key, existingValues === undefined
                ? [...value]
                : [...guaranteeNonNullable(existingValues), ...value]);
        });
        return elementTypesWithCategoryMap;
    }
    getSupportedElementTypes() {
        return [
            PACKAGEABLE_ELEMENT_TYPE.CLASS,
            PACKAGEABLE_ELEMENT_TYPE.ENUMERATION,
            PACKAGEABLE_ELEMENT_TYPE.PROFILE,
            PACKAGEABLE_ELEMENT_TYPE.ASSOCIATION,
            PACKAGEABLE_ELEMENT_TYPE.FUNCTION,
            PACKAGEABLE_ELEMENT_TYPE.MEASURE,
        ].concat([
            PACKAGEABLE_ELEMENT_TYPE.MAPPING,
            PACKAGEABLE_ELEMENT_TYPE.RUNTIME,
            PACKAGEABLE_ELEMENT_TYPE.CONNECTION,
            PACKAGEABLE_ELEMENT_TYPE.SERVICE,
            PACKAGEABLE_ELEMENT_TYPE.GENERATION_SPECIFICATION,
            PACKAGEABLE_ELEMENT_TYPE.FILE_GENERATION,
            PACKAGEABLE_ELEMENT_TYPE.FLAT_DATA_STORE,
            PACKAGEABLE_ELEMENT_TYPE.DATABASE,
            PACKAGEABLE_ELEMENT_TYPE.DATA,
            this.applicationStore.config.options
                .TEMPORARY__enableLocalConnectionBuilder
                ? PACKAGEABLE_ELEMENT_TYPE.TEMPORARY__LOCAL_CONNECTION
                : undefined,
        ]
            .filter(isNonNullable)
            .concat(this.pluginManager
            .getApplicationPlugins()
            .flatMap((plugin) => plugin.getExtraSupportedElementTypes?.() ?? []))
            .sort((a, b) => a.localeCompare(b)));
    }
    *switchModes(to, fallbackOptions) {
        switch (to) {
            case GRAPH_EDITOR_MODE.GRAMMAR_TEXT: {
                const graphEditorMode = new GraphEditGrammarModeState(this);
                try {
                    yield flowResult(this.graphEditorMode.onLeave(fallbackOptions));
                    yield flowResult(graphEditorMode.cleanupBeforeEntering(fallbackOptions));
                    this.graphEditorMode = graphEditorMode;
                    yield flowResult(this.graphEditorMode.initialize(fallbackOptions));
                }
                catch (error) {
                    assertErrorThrown(error);
                    this.applicationStore.notificationService.notifyWarning(`Can't enter text mode: transformation to grammar text failed. Error: ${error.message}`);
                    this.applicationStore.alertService.setBlockingAlert(undefined);
                    return;
                }
                break;
            }
            case GRAPH_EDITOR_MODE.FORM: {
                if (this.graphState.checkIfApplicationUpdateOperationIsRunning()) {
                    return;
                }
                try {
                    try {
                        yield flowResult(this.graphEditorMode.onLeave(fallbackOptions));
                        this.graphEditorMode = new GraphEditFormModeState(this);
                        yield flowResult(this.graphEditorMode.initialize());
                    }
                    catch (error) {
                        yield flowResult(this.graphEditorMode.handleCleanupFailure(error));
                    }
                }
                catch (error) {
                    assertErrorThrown(error);
                    this.applicationStore.logService.error(LogEvent.create(GRAPH_MANAGER_EVENT.COMPILATION_FAILURE), error);
                }
                finally {
                    this.graphState.isApplicationLeavingGraphEditMode = false;
                    this.applicationStore.alertService.setBlockingAlert(undefined);
                    this.changeDetectionState.workspaceLocalLatestRevisionState.currentEntityHashesIndex =
                        new Map();
                }
                break;
            }
            default:
                throw new UnsupportedOperationError(`Editor does not support ${to} mode at the moment `);
        }
    }
    getGraphEditorMode(clazz) {
        return guaranteeType(this.graphEditorMode, clazz, `Graph editor mode is not of the specified type (this is likely caused by calling this method at the wrong place)`);
    }
}
//# sourceMappingURL=EditorStore.js.map