"use strict";
var ExtensionServiceImpl_1;
Object.defineProperty(exports, "__esModule", { value: true });
exports.ExtensionServiceImpl = void 0;
const tslib_1 = require("tslib");
const debounce_1 = tslib_1.__importDefault(require("lodash/debounce"));
const di_1 = require("@opensumi/di");
const browser_1 = require("@opensumi/ide-connection/lib/browser");
const server_handler_1 = require("@opensumi/ide-connection/lib/common/server-handler");
const ide_core_browser_1 = require("@opensumi/ide-core-browser");
const progress_1 = require("@opensumi/ide-core-browser/lib/progress");
const ide_core_common_1 = require("@opensumi/ide-core-common");
const ide_debug_1 = require("@opensumi/ide-debug");
const ide_extension_storage_1 = require("@opensumi/ide-extension-storage");
const common_1 = require("@opensumi/ide-file-search/lib/common");
const ide_file_service_1 = require("@opensumi/ide-file-service");
const ide_overlay_1 = require("@opensumi/ide-overlay");
const ide_workspace_1 = require("@opensumi/ide-workspace");
const common_2 = require("../common");
const extension_service_1 = require("../common/extension.service");
const vscode_1 = require("../common/vscode");
const activation_service_1 = require("./activation.service");
const contributes_1 = require("./sumi/contributes");
const types_1 = require("./types");
const contributes_2 = require("./vscode/contributes");
let ExtensionServiceImpl = ExtensionServiceImpl_1 = class ExtensionServiceImpl extends ide_core_common_1.WithEventBus {
    constructor() {
        super();
        /**
         * 这里的 ready 是区分环境，将 node/worker 区分开使用
         */
        this.ready = new Map();
        // 插件进程是否正在重启中
        this.isExtProcessRestarting = false;
        // 是否正在显示插件重启的 loading 状态
        this.isProgressShowing = false;
        // 针对 activationEvents 为 * 的插件
        this.eagerExtensionsActivated = new ide_core_browser_1.Deferred();
        /**
         * 插件目录
         * 主要为插件的读取目录
         */
        this.extensionScanDir = new Set();
        /**
         * 补充的插件列表
         * 主要为插件的读取路径
         */
        this.extensionCandidatePath = new Set();
        this.restartProgress = async (restartPolicy = common_2.ERestartPolicy.Always) => {
            const doRestart = async (token) => {
                this.disposeAllOverlayWindow();
                token.onCancellationRequested(() => {
                    this.logger.log('[ext-restart]: ext process restart canceled');
                    this.isExtProcessRestarting = false;
                    this.isExtProcessWaitingForRestart = undefined;
                    this.isProgressShowing = false;
                });
                try {
                    await this.startExtProcess(false);
                }
                catch (err) {
                    this.logger.error(`[ext-restart]: ext-host restart failure, error: ${err}`);
                }
                this.isExtProcessRestarting = false;
                this.isExtProcessWaitingForRestart = undefined;
                this.isProgressShowing = false;
                this.disposeAllOverlayWindow();
            };
            await this.channelHandler.awaitChannelReady(server_handler_1.RPCServiceChannelPath);
            const policy = this.isExtProcessWaitingForRestart || restartPolicy;
            this.logger.log('[ext-restart]: restart ext process, restart policy:', policy);
            switch (policy) {
                // @ts-expect-error Need fall-through
                case common_2.ERestartPolicy.WhenExit:
                    // if we can get the pid, then the process is still running, no need to restart.
                    // if pid is null, it means the process is exited, then we need to start it.
                    if (await this.getExtProcessPID()) {
                        this.logger.log('[ext-restart]: ext process is still running, skip');
                        break;
                    }
                case common_2.ERestartPolicy.Always:
                    if (this.isProgressShowing) {
                        this.logger.log('[ext-restart]: progress is already showing, skip');
                        return;
                    }
                    this.isProgressShowing = true;
                    await this.progressService.withProgress({
                        location: ide_core_common_1.ProgressLocation.Notification,
                        title: (0, ide_core_common_1.localize)('extension.exthostRestarting.content'),
                        buttons: [
                            {
                                id: 'extension.reload',
                                label: (0, ide_core_common_1.localize)('preference.general.language.change.refresh.now'),
                                primary: true,
                                run: async () => {
                                    this.clientApp.fireOnReload();
                                },
                                dispose: () => { },
                            },
                        ],
                    }, async () => {
                        // doRestart 存在严重的副作用且不可 Cancel，因此单次重启只允许执行一次
                        this.extProcessRestartPromise = (0, ide_core_common_1.createCancelablePromise)(doRestart);
                        await this.extProcessRestartPromise;
                    });
                    break;
            }
            this.isExtProcessRestarting = false;
        };
        this.restartDebounced = (0, debounce_1.default)(async () => {
            await this.restartProgress();
        }, 500);
        this.addDispose(this.fileServiceClient.onWillActivateFileSystemProvider(async () => {
            if (!this.extensionMetaDataArr) {
                await this.initExtensionMetaData();
            }
            return this.activationEventService.getTopicsData('onFileSystem');
        }));
    }
    /**
     * @internal 提供获取所有运行中的插件的列表数据
     */
    async getActivatedExtensions() {
        const activated = {};
        if (this.nodeExtensionService.protocol) {
            activated['node'] = await this.nodeExtensionService.getActivatedExtensions();
        }
        if (this.workerExtensionService.protocol) {
            activated['worker'] = await this.workerExtensionService.getActivatedExtensions();
        }
        return activated;
    }
    async onActivateExtension(e) {
        await this.activationEventService.fireEvent(e.payload.topic, e.payload.data);
    }
    /**
     * 插件激活后需更新插件进程数据
     */
    async onExtensionEnabled(e) {
        const extension = e.payload;
        await this.updateExtHostData();
        await this.fireActivationEventsIfNeed(extension.packageJSON.activationEvents);
    }
    /**
     * 插件卸载后需更新插件进程数据
     */
    async onExtensionUninstalled() {
        await this.updateExtHostData();
    }
    async activate() {
        await this.initExtensionMetaData();
        await this.initExtensionInstanceData();
        await this.runEagerExtensionsContributes();
        // update nls config by extensions
        await this.setupExtensionNLSConfig();
        this.doActivate();
        // 监听页面展示状态，当页面状态变为可见且插件进程待重启的时候执行
        const onPageVisibilitychange = () => {
            this.logger.log('[ext-restart]: page visibility change, current:', document.visibilityState, 'is waiting:', this.isExtProcessWaitingForRestart, 'is restarting:', this.isExtProcessRestarting);
            if (document.visibilityState === 'visible' &&
                this.isExtProcessWaitingForRestart &&
                !this.isExtProcessRestarting) {
                this.extProcessRestartHandler(this.isExtProcessWaitingForRestart);
            }
        };
        document.addEventListener('visibilitychange', onPageVisibilitychange, false);
        this.addDispose(ide_core_browser_1.Disposable.create(() => {
            document.removeEventListener('visibilitychange', onPageVisibilitychange);
        }));
    }
    async setupExtensionNLSConfig() {
        const storagePath = (await this.extensionStoragePathServer.getLastStoragePath()) || '';
        const currentLanguage = this.preferenceService.get(ide_core_common_1.GeneralSettingsId.Language) || (0, ide_core_common_1.getLanguageId)();
        await this.extensionNodeClient.setupNLSConfig(currentLanguage, storagePath);
    }
    /**
     * 初始化插件列表数据
     * 包括插件目录和插件 Candidate
     * 以及 ExtensionMetaData
     */
    async initExtensionMetaData() {
        const { extensionDir, extensionCandidate } = this.appConfig;
        if (extensionDir) {
            this.extensionScanDir.add(extensionDir);
        }
        if (extensionCandidate) {
            extensionCandidate.forEach((extension) => {
                this.extensionCandidatePath.add(extension.path);
            });
        }
        await this.getExtensionsMetaData(Array.from(this.extensionScanDir), Array.from(this.extensionCandidatePath));
    }
    /**
     * 初始化插件实例数据
     */
    async initExtensionInstanceData() {
        for (const extensionMetaData of this.extensionMetaDataArr) {
            const isBuiltin = this.extensionInstanceManageService.checkIsBuiltin(extensionMetaData);
            const isDevelopment = this.extensionInstanceManageService.checkIsDevelopment(extensionMetaData);
            const extension = await this.extensionInstanceManageService.createExtensionInstance(extensionMetaData, isBuiltin, isDevelopment);
            if (extension) {
                this.extensionInstanceManageService.addExtensionInstance(extension);
            }
            if ((extension === null || extension === void 0 ? void 0 : extension.contributes) && extension.enabled) {
                this.contributesService.register(extension.id, extension.contributes);
                this.sumiContributesService.register(extension.id, extension.packageJSON.sumiContributes || {});
            }
        }
        this.eventBus.fire(new types_1.ExtensionsInitializedEvent(this.extensionInstanceManageService.getExtensionInstances()));
        this.eventBus.fire(new ide_debug_1.DebugConfigurationsReadyEvent(undefined));
        const extensionInstanceList = this.extensionInstanceManageService.getExtensionInstances();
        this.nodeExtensionService.updateExtensionData(extensionInstanceList);
        this.workerExtensionService.updateExtensionData(extensionInstanceList);
        this.viewExtensionService.initExtension(extensionInstanceList);
    }
    async doActivate() {
        await this.workspaceService.whenReady;
        await this.extensionStorageService.whenReady;
        await this.viewExtensionService.activate();
        // 启动插件进程
        await this.startExtProcess(true);
        try {
            await this.eventBus.fireAndAwait(new types_1.ExtensionBeforeActivateEvent());
            await this.activationEventService.fireEvent('*');
        }
        catch (err) {
            this.logger.error(`[Extension Activate Error], \n ${err.message || err}`);
        }
        finally {
            // 表示 * 的插件全部激活完了
            this.eagerExtensionsActivated.resolve();
            this.activationEventService.fireEvent('onStartupFinished');
            // 表示 * 的插件可以调了
            this.eventBus.fire(new types_1.ExtensionApiReadyEvent());
        }
    }
    /**
     * 重启插件进程
     */
    async restartExtProcess(restartPolicy = common_2.ERestartPolicy.Always) {
        /**
         * 只有在页面可见的情况下才执行插件进程重启操作
         * 如果当前页面不可见，那么 chrome 会对 socket 进行限流，导致进程重启的 rpc 调用得不到返回从而卡住
         */
        if (document.visibilityState === 'visible') {
            this.extProcessRestartHandler(restartPolicy);
        }
        else {
            this.logger.log('[ext-restart]: page is not visible, waiting for restart, policy:', restartPolicy);
            this.isExtProcessWaitingForRestart = restartPolicy;
        }
    }
    disposeAllOverlayWindow() {
        var _a, _b;
        if (this.pCrashMessageModel) {
            // crash message model is still open, close it
            (_b = (_a = this.pCrashMessageModel).cancel) === null || _b === void 0 ? void 0 : _b.call(_a);
            this.pCrashMessageModel = undefined;
        }
    }
    async extProcessRestartHandler(restartPolicy = common_2.ERestartPolicy.Always) {
        if (this.isExtProcessRestarting && restartPolicy !== common_2.ERestartPolicy.Always) {
            this.logger.log('[ext-restart]: ext process is restarting, skip');
            return;
        }
        this.isExtProcessRestarting = true;
        if (this.isExtProcessWaitingForRestart) {
            /**
             * 只有当页面不可见的时候被通知执行重启操作，isExtProcessWaitingForRestart 才会为 true
             * 目前观察到页面从不可见恢复至可见状态后，可能出现 socket 堆积的现象，因此延迟 1000ms 后再进行重启操作
             * 这里延时并不能保证一定能够正确重启，只是降低失败的可能性。在解决了 socket 堆积的情况后，可以直接去掉
             */
            this.restartDebounced();
        }
        else {
            this.restartProgress(restartPolicy);
        }
    }
    async getExtProcessPID() {
        return await Promise.race([
            this.extensionNodeClient.pid().catch(async (err) => {
                this.logger.error(`[ext-restart]: get ext process pid error, ${err}`);
                await (0, ide_core_common_1.sleep)(200);
                return null;
            }),
            (0, ide_core_common_1.sleep)(1000).then(() => null),
        ]);
    }
    async startExtProcess(init) {
        /**
         * 重启插件进程步骤：
         * 1、重置所有插件实例的状态至未激活
         * 2、dispose 掉所有被激活且在 contributes 里申明过 browserView 的 sumi 插件
         * 3、将负责前后端通信的 main.thread 全部 dispose 掉
         * 4、杀掉后端插件进程
         * 5、走正常激活插件流程，重新激活对应插件进程
         * 6、将之前已经激活的插件重新激活一遍
         */
        if (!init) {
            this.resetExtensionInstances();
            this.disposeSumiViewExtension();
            await this.disposeExtProcess();
        }
        // set ready for node/worker
        await Promise.all([this.startNodeExtHost(init), this.startWorkerExtHost(init)]);
        if (!init) {
            // 重启场景下需要将申明过 browserView 的 sumi 插件的 contributes 重新跑一遍
            await this.rerunSumiViewExtensionContributes();
            // 重启场景下把 ActivationEvent 再发一次
            if (this.activationEventService.activatedEventSet.size) {
                const activatedEventArr = Array.from(this.activationEventService.activatedEventSet);
                this.activationEventService.activatedEventSet.clear();
                await Promise.allSettled(activatedEventArr.map((event) => {
                    const { topic, data } = JSON.parse(event);
                    this.logger.verbose('fireEvent', 'event.topic', topic, 'event.data', data);
                    return this.activationEventService.fireEvent(topic, data);
                }));
            }
        }
    }
    async startNodeExtHost(init) {
        if (this.appConfig.noExtHost) {
            return;
        }
        // 激活 node 插件进程
        const protocol = await this.nodeExtensionService.activate();
        this.extensionCommandManager.registerProxyCommandExecutor('node', protocol.get(vscode_1.MainThreadAPIIdentifier.MainThreadCommands));
        if (init) {
            this.ready.set('node', this.nodeExtensionService.ready);
        }
    }
    async startWorkerExtHost(init) {
        // 激活 worker 插件进程
        if (!this.appConfig.extWorkerHost) {
            return;
        }
        try {
            const protocol = await this.workerExtensionService.activate(this.appConfig.ignoreWorkerHostCors);
            this.extensionCommandManager.registerProxyCommandExecutor('worker', protocol.get(vscode_1.MainThreadAPIIdentifier.MainThreadCommands));
            if (init) {
                this.ready.set('worker', this.workerExtensionService.ready);
            }
        }
        catch (err) {
            this.logger.error(`Worker host activate fail, \n ${err.message}`);
        }
    }
    /**
     * 更新插件进程中插件的数据
     */
    async updateExtHostData() {
        const extensions = this.extensionInstanceManageService.getExtensionInstances();
        if (!this.appConfig.noExtHost) {
            await this.nodeExtensionService.updateExtensionData(extensions);
        }
        if (this.appConfig.extWorkerHost) {
            await this.workerExtensionService.updateExtensionData(extensions);
        }
    }
    /**
     * 发送 ActivationEvents
     */
    async fireActivationEventsIfNeed(activationEvents) {
        if (!Array.isArray(activationEvents) || !activationEvents.length) {
            return;
        }
        const startUpActivationEvents = ['*', 'onStartupFinished'];
        const _activationEvents = activationEvents.filter((event) => event !== '*');
        const shouldFireEvents = Array.from(this.activationEventService.activatedEventSet)
            .map((event) => JSON.parse(event))
            .filter(({ topic, data }) => _activationEvents.find((_event) => _event === `${topic}:${data}`));
        for (const event of startUpActivationEvents) {
            if (activationEvents.includes(event)) {
                this.logger.verbose(`Fire activation event ${event}`);
                this.activationEventService.fireEvent(event);
            }
        }
        for (const event of shouldFireEvents) {
            const { topic, data } = event;
            this.logger.verbose(`Fire activation event ${topic}:${data}`);
            this.activationEventService.fireEvent(topic, data);
        }
        await this.activateByWorkspaceContains(activationEvents);
    }
    async activateByWorkspaceContains(activationEvents) {
        if (!Array.isArray(activationEvents) || !activationEvents.length) {
            return;
        }
        const paths = [];
        const includePatterns = [];
        for (const activationEvent of activationEvents) {
            if (/^workspaceContains:/.test(activationEvent)) {
                const fileNameOrGlob = activationEvent.substr('workspaceContains:'.length);
                if (fileNameOrGlob.indexOf('*') >= 0 || fileNameOrGlob.indexOf('?') >= 0) {
                    includePatterns.push(fileNameOrGlob);
                }
                else {
                    paths.push(fileNameOrGlob);
                }
            }
        }
        const promises = [];
        if (paths.length) {
            promises.push(this.workspaceService.containsSome(paths));
        }
        if (includePatterns.length) {
            promises.push((async () => {
                try {
                    const result = await this.fileSearchService.find('', {
                        rootUris: this.workspaceService.tryGetRoots().map((stat) => new ide_core_common_1.URI(stat.uri).codeUri.fsPath),
                        includePatterns,
                        limit: 1,
                    });
                    return result.length > 0;
                }
                catch (e) {
                    this.logger.error(e);
                    return false;
                }
            })());
        }
        if (promises.length && (await Promise.all(promises).then((exists) => exists.some((v) => v)))) {
            this.activationEventService.fireEvent('workspaceContains', [...paths, ...includePatterns][0]);
        }
    }
    /**
     * 将插件的目录位置和文件位置，通过后端读取并缓存
     * 返回所有插件的 meta data
     */
    async getExtensionsMetaData(extensionScanDir, extensionCandidatePath) {
        if (!this.extensionMetaDataArr) {
            const extensions = await this.extensionNodeClient.getAllExtensions(extensionScanDir, extensionCandidatePath, (0, ide_core_common_1.getLanguageId)(), ExtensionServiceImpl_1.extraMetadata);
            this.extensionMetaDataArr = extensions;
        }
        this.logger.log('extensions count:', this.extensionMetaDataArr.length);
        return this.extensionMetaDataArr;
    }
    async runEagerExtensionsContributes() {
        await Promise.all([this.contributesService.initialize(), this.sumiContributesService.initialize()]);
        this.commandRegistry.beforeExecuteCommand(async (command, args) => {
            await this.activationEventService.fireEvent('onCommand', command);
            return args;
        });
        this.eventBus.fire(new ide_core_common_1.ExtensionDidContributes());
    }
    /**
     * 激活插件的 Contributes
     */
    async runExtensionContributes() {
        const extensions = Array.from(this.extensionInstanceManageService.getExtensionInstances());
        // try fire workspaceContains activateEvent ，这里不要 await
        Promise.all(extensions.map((extension) => this.activateByWorkspaceContains(extension.packageJSON.activationEvents))).catch((error) => this.logger.error(error));
    }
    /**
     * 判断是否是 web 插件
     * 这里会多增加一个判断：是否启动了 node-ext-host
     * https://code.visualstudio.com/api/extension-guides/web-extensions#web-extension-enablement
     */
    whetherWebExtension({ packageJSON }) {
        const { browser, main } = packageJSON || {};
        const noExtHost = Boolean(this.appConfig.noExtHost);
        // 如果只包含 browser 入口
        if (browser && !main) {
            return true;
        }
        // 如果同时包含两个入口，那么判断是否启动了node插件进程
        if (browser && main) {
            return noExtHost;
        }
        // 只包含 main 入
        if (!browser && main) {
            return false;
        }
        /**
         * 都不包含的情况下：
         * 如果contributes中含有'debuggers', 'terminal', 'typescriptServerPlugins'三个之一，那么不作为web插件启动
         * 如果不包含，那么判断是否启动了node插件进程
         */
        if (typeof packageJSON.contributes !== 'undefined') {
            for (const id of ['debuggers', 'terminal', 'typescriptServerPlugins']) {
                if (packageJSON.contributes.hasOwnProperty(id)) {
                    return false;
                }
            }
        }
        return noExtHost;
    }
    /**
     * 给 Extension 使用 | 激活插件
     */
    async activeExtension(extension) {
        const isWebExtension = this.whetherWebExtension(extension);
        if (isWebExtension && !this.appConfig.extWorkerHost) {
            this.logger.error('[extension.service]: has no ext worker host');
        }
        // 优先激活 Node 和 Worker 进程中的插件
        // 这个时序下，不允许存在 Node/Worker 互相依赖的情况
        // 插件 Browser 中可以依赖 Node/Worker
        await Promise.all([
            this.nodeExtensionService.activeExtension(extension, isWebExtension),
            this.workerExtensionService.activeExtension(extension, isWebExtension),
        ]);
        await this.viewExtensionService.activeExtension(extension, this.nodeExtensionService.protocol);
        this.eventBus.fire(new ide_core_common_1.ExtensionActivatedEvent({ topic: 'onExtensionActivated', data: { id: extension.id } }));
    }
    resetExtensionInstances() {
        this.extensionInstanceManageService.resetExtensionInstances();
        this.nodeExtensionService.disposeApiFactory();
        this.workerExtensionService.disposeApiFactory();
    }
    /**
     * 每次激活 sumi 插件的时候，都会尝试去激活 sumiContributes 中的 browserView，会导致 browserView 重复注册
     * 因此重启场景下需要先将这部分被激活的插件 dispose 掉
     */
    disposeSumiViewExtension() {
        const paths = Array.from(this.viewExtensionService.activatedViewExtensionMap.keys());
        this.extensionInstanceManageService.disposeExtensionInstancesByPath(paths);
    }
    async rerunSumiViewExtensionContributes() {
        const { activatedViewExtensionMap } = this.viewExtensionService;
        const extensionPaths = Array.from(activatedViewExtensionMap.keys());
        await Promise.all(extensionPaths.map((path) => {
            const extension = this.extensionInstanceManageService.getExtensionInstanceByPath(path);
            if (extension) {
                extension.initialize();
                this.sumiContributesService.register(extension.id, extension.packageJSON.sumiContributes || {});
            }
        }));
        activatedViewExtensionMap.clear();
        await Promise.all([this.contributesService.initialize(), this.sumiContributesService.initialize()]);
    }
    async disposeExtProcess() {
        await this.nodeExtensionService.disposeProcess();
        await this.workerExtensionService.disposeProcess();
    }
    async disposeExtensions() {
        // 重置掉插件实例
        this.extensionInstanceManageService.disposeExtensionInstances();
    }
    // 给 contributes#command 注册 command executor 使用
    async executeExtensionCommand(command, args) {
        var _a;
        const targetEnv = this.extensionCommandManager.getExtensionCommandEnv(command);
        if (!targetEnv) {
            throw new Error('No Command with id "' + command + '" is declared by extensions');
        }
        // 需要等待对应插件进程启动完成再执行指令
        await ((_a = this.ready.get(targetEnv)) === null || _a === void 0 ? void 0 : _a.promise);
        // 这里相比之前有个变化，之前是先找 command 存不存在，然后等 ready 再执行
        // 现在是先等 ready 再去找 command 再去执行
        return this.extensionCommandManager.executeExtensionCommand(targetEnv, command, args);
    }
    // 暴露给后端调用前端时使用，用来处理插件进程不存在和 crash/restart 时的弹窗
    get invalidReloadStrategy() {
        // 获取corePreferences配置判断是否弹出确认框
        return this.corePreferences['application.invalidExthostReload'];
    }
    // RPC call from node
    async $restartExtProcess() {
        this.logger.log('[ext-restart]: receive the command from the node side to restart the process');
        await this.restartExtProcess(common_2.ERestartPolicy.Always);
    }
    async $processNotExist() {
        // if browser receive the message, means the connection is keep alive
        // so we still need to restart the ext process
        this.logger.log('[ext-restart]: receive the command from the node side that the process does not exist');
        this.$restartExtProcess();
        return 'ok';
    }
    async showReloadWindow() {
        const okText = (0, ide_core_common_1.localize)('extension.invalidExthostReload.confirm.ok');
        const options = [okText];
        const ifRequiredReload = this.invalidReloadStrategy === 'ifRequired';
        if (ifRequiredReload) {
            options.unshift((0, ide_core_common_1.localize)('extension.invalidExthostReload.confirm.cancel'));
        }
        const msg = await this.dialogService.info((0, ide_core_common_1.localize)('extension.invalidExthostReload.confirm.content'), options, !!ifRequiredReload);
        if (msg === okText) {
            this.clientApp.fireOnReload();
        }
    }
    async $processCrashRestart() {
        var _a, _b;
        if (this.pCrashMessageModel) {
            (_b = (_a = this.pCrashMessageModel).cancel) === null || _b === void 0 ? void 0 : _b.call(_a);
        }
        const okText = (0, ide_core_common_1.localize)('common.yes');
        const options = [okText];
        const ifRequiredReload = this.invalidReloadStrategy === 'ifRequired';
        if (ifRequiredReload) {
            options.unshift((0, ide_core_common_1.localize)('common.no'));
        }
        this.pCrashMessageModel = this.messageService.info((0, ide_core_common_1.localize)('extension.crashedExthostReload.confirm'), options, !!ifRequiredReload);
        const msg = await this.pCrashMessageModel;
        this.pCrashMessageModel = undefined;
        if (msg === okText) {
            await this.restartExtProcess(common_2.ERestartPolicy.Always);
        }
    }
};
exports.ExtensionServiceImpl = ExtensionServiceImpl;
ExtensionServiceImpl.extraMetadata = {
    [common_2.LANGUAGE_BUNDLE_FIELD]: './package.nls.json',
};
tslib_1.__decorate([
    (0, di_1.Autowired)(common_2.ExtensionNodeServiceServerPath),
    tslib_1.__metadata("design:type", Object)
], ExtensionServiceImpl.prototype, "extensionNodeClient", void 0);
tslib_1.__decorate([
    (0, di_1.Autowired)(ide_core_browser_1.AppConfig),
    tslib_1.__metadata("design:type", Object)
], ExtensionServiceImpl.prototype, "appConfig", void 0);
tslib_1.__decorate([
    (0, di_1.Autowired)(ide_core_browser_1.CommandRegistry),
    tslib_1.__metadata("design:type", Object)
], ExtensionServiceImpl.prototype, "commandRegistry", void 0);
tslib_1.__decorate([
    (0, di_1.Autowired)(types_1.IActivationEventService),
    tslib_1.__metadata("design:type", activation_service_1.ActivationEventServiceImpl)
], ExtensionServiceImpl.prototype, "activationEventService", void 0);
tslib_1.__decorate([
    (0, di_1.Autowired)(ide_workspace_1.IWorkspaceService),
    tslib_1.__metadata("design:type", Object)
], ExtensionServiceImpl.prototype, "workspaceService", void 0);
tslib_1.__decorate([
    (0, di_1.Autowired)(ide_extension_storage_1.IExtensionStorageService),
    tslib_1.__metadata("design:type", Object)
], ExtensionServiceImpl.prototype, "extensionStorageService", void 0);
tslib_1.__decorate([
    (0, di_1.Autowired)(progress_1.IProgressService),
    tslib_1.__metadata("design:type", Object)
], ExtensionServiceImpl.prototype, "progressService", void 0);
tslib_1.__decorate([
    (0, di_1.Autowired)(ide_overlay_1.IDialogService),
    tslib_1.__metadata("design:type", Object)
], ExtensionServiceImpl.prototype, "dialogService", void 0);
tslib_1.__decorate([
    (0, di_1.Autowired)(ide_core_browser_1.IClientApp),
    tslib_1.__metadata("design:type", Object)
], ExtensionServiceImpl.prototype, "clientApp", void 0);
tslib_1.__decorate([
    (0, di_1.Autowired)(ide_core_browser_1.ILogger),
    tslib_1.__metadata("design:type", Object)
], ExtensionServiceImpl.prototype, "logger", void 0);
tslib_1.__decorate([
    (0, di_1.Autowired)(ide_overlay_1.IMessageService),
    tslib_1.__metadata("design:type", Object)
], ExtensionServiceImpl.prototype, "messageService", void 0);
tslib_1.__decorate([
    (0, di_1.Autowired)(ide_core_browser_1.CorePreferences),
    tslib_1.__metadata("design:type", Object)
], ExtensionServiceImpl.prototype, "corePreferences", void 0);
tslib_1.__decorate([
    (0, di_1.Autowired)(extension_service_1.AbstractWorkerExtProcessService),
    tslib_1.__metadata("design:type", extension_service_1.AbstractWorkerExtProcessService)
], ExtensionServiceImpl.prototype, "workerExtensionService", void 0);
tslib_1.__decorate([
    (0, di_1.Autowired)(extension_service_1.AbstractNodeExtProcessService),
    tslib_1.__metadata("design:type", extension_service_1.AbstractNodeExtProcessService)
], ExtensionServiceImpl.prototype, "nodeExtensionService", void 0);
tslib_1.__decorate([
    (0, di_1.Autowired)(extension_service_1.AbstractViewExtProcessService),
    tslib_1.__metadata("design:type", extension_service_1.AbstractViewExtProcessService)
], ExtensionServiceImpl.prototype, "viewExtensionService", void 0);
tslib_1.__decorate([
    (0, di_1.Autowired)(common_2.IExtCommandManagement),
    tslib_1.__metadata("design:type", common_2.IExtCommandManagement)
], ExtensionServiceImpl.prototype, "extensionCommandManager", void 0);
tslib_1.__decorate([
    (0, di_1.Autowired)(types_1.AbstractExtInstanceManagementService),
    tslib_1.__metadata("design:type", types_1.AbstractExtInstanceManagementService)
], ExtensionServiceImpl.prototype, "extensionInstanceManageService", void 0);
tslib_1.__decorate([
    (0, di_1.Autowired)(common_1.FileSearchServicePath),
    tslib_1.__metadata("design:type", Object)
], ExtensionServiceImpl.prototype, "fileSearchService", void 0);
tslib_1.__decorate([
    (0, di_1.Autowired)(contributes_2.VSCodeContributesServiceToken),
    tslib_1.__metadata("design:type", contributes_2.VSCodeContributesService)
], ExtensionServiceImpl.prototype, "contributesService", void 0);
tslib_1.__decorate([
    (0, di_1.Autowired)(contributes_1.SumiContributionsServiceToken),
    tslib_1.__metadata("design:type", contributes_1.SumiContributionsService)
], ExtensionServiceImpl.prototype, "sumiContributesService", void 0);
tslib_1.__decorate([
    (0, di_1.Autowired)(ide_core_browser_1.PreferenceService),
    tslib_1.__metadata("design:type", Object)
], ExtensionServiceImpl.prototype, "preferenceService", void 0);
tslib_1.__decorate([
    (0, di_1.Autowired)(ide_extension_storage_1.IExtensionStoragePathServer),
    tslib_1.__metadata("design:type", Object)
], ExtensionServiceImpl.prototype, "extensionStoragePathServer", void 0);
tslib_1.__decorate([
    (0, di_1.Autowired)(di_1.INJECTOR_TOKEN),
    tslib_1.__metadata("design:type", di_1.Injector)
], ExtensionServiceImpl.prototype, "injector", void 0);
tslib_1.__decorate([
    (0, di_1.Autowired)(ide_file_service_1.IFileServiceClient),
    tslib_1.__metadata("design:type", Object)
], ExtensionServiceImpl.prototype, "fileServiceClient", void 0);
tslib_1.__decorate([
    (0, di_1.Autowired)(browser_1.WSChannelHandler),
    tslib_1.__metadata("design:type", browser_1.WSChannelHandler)
], ExtensionServiceImpl.prototype, "channelHandler", void 0);
tslib_1.__decorate([
    (0, ide_core_common_1.OnEvent)(ide_core_browser_1.ExtensionActivateEvent),
    tslib_1.__metadata("design:type", Function),
    tslib_1.__metadata("design:paramtypes", [ide_core_browser_1.ExtensionActivateEvent]),
    tslib_1.__metadata("design:returntype", Promise)
], ExtensionServiceImpl.prototype, "onActivateExtension", null);
tslib_1.__decorate([
    (0, ide_core_common_1.OnEvent)(types_1.ExtensionDidEnabledEvent),
    tslib_1.__metadata("design:type", Function),
    tslib_1.__metadata("design:paramtypes", [types_1.ExtensionDidEnabledEvent]),
    tslib_1.__metadata("design:returntype", Promise)
], ExtensionServiceImpl.prototype, "onExtensionEnabled", null);
tslib_1.__decorate([
    (0, ide_core_common_1.OnEvent)(types_1.ExtensionDidUninstalledEvent),
    tslib_1.__metadata("design:type", Function),
    tslib_1.__metadata("design:paramtypes", []),
    tslib_1.__metadata("design:returntype", Promise)
], ExtensionServiceImpl.prototype, "onExtensionUninstalled", null);
exports.ExtensionServiceImpl = ExtensionServiceImpl = ExtensionServiceImpl_1 = tslib_1.__decorate([
    (0, di_1.Injectable)(),
    tslib_1.__metadata("design:paramtypes", [])
], ExtensionServiceImpl);
//# sourceMappingURL=extension.service.js.map