private updateOpenedDocument()

in src/AzureRMTools.ts [557:683]


    private updateOpenedDocument(textDocument: vscode.TextDocument): void {
        // tslint:disable-next-line:no-suspicious-comment
        // TODO: refactor
        // tslint:disable-next-line: cyclomatic-complexity max-func-body-length
        callWithTelemetryAndErrorHandlingSync('updateDeploymentDocument', (actionContext: IActionContext): void => {
            actionContext.errorHandling.suppressDisplay = true;
            actionContext.telemetry.suppressIfSuccessful = true;
            actionContext.telemetry.properties.isActivationEvent = 'true';
            actionContext.telemetry.properties.fileExt = path.extname(textDocument.fileName);

            assert(textDocument);
            const editor: vscode.TextEditor | undefined = vscode.window.activeTextEditor;
            const stopwatch = new Stopwatch();
            stopwatch.start();

            let treatAsDeploymentTemplate = false;
            let treatAsDeploymentParameters = false;
            const documentUri = textDocument.uri;

            if (textDocument.languageId === armTemplateLanguageId) {
                // Lang ID is set to arm-template, whether auto or manual, respect the setting
                treatAsDeploymentTemplate = true;
            }

            // If the documentUri is not in our dictionary of deployment templates, then either
            //   it's not a deployment file, or else this document was just opened (as opposed
            //   to changed/updated).
            // Note that it might have been opened, then closed, then reopened, or it
            //   might have had its schema changed in the editor to make it a deployment file.
            const isNewlyOpened: boolean = !this.getOpenedDeploymentDocument(documentUri);

            // Is it a deployment template file?
            let shouldParseFile = treatAsDeploymentTemplate || mightBeDeploymentTemplate(textDocument);
            if (shouldParseFile) {
                // Do a full parse
                let deploymentTemplate: DeploymentTemplateDoc = new DeploymentTemplateDoc(textDocument.getText(), documentUri, textDocument.version);
                if (deploymentTemplate.hasArmSchemaUri()) {
                    treatAsDeploymentTemplate = true;
                }
                actionContext.telemetry.measurements.parseDurationInMilliseconds = stopwatch.duration.totalMilliseconds;

                if (treatAsDeploymentTemplate) {
                    this.ensureDeploymentDocumentEventsHookedUp();

                    this.setOpenedDeploymentDocument(documentUri, deploymentTemplate);
                    this.registerActiveUse();

                    if (isNewlyOpened) {
                        // A deployment template has been opened (as opposed to having been tabbed to)

                        // Make sure the language ID is set to arm-template
                        if (textDocument.languageId !== armTemplateLanguageId) {
                            // The document will be reloaded, firing this event again with the new langid
                            setLangIdToArm(textDocument, actionContext);
                            return;
                        }
                    }

                    // Not waiting for return
                    let errorsWarnings: IErrorsAndWarnings | undefined = this.reportDeploymentTemplateErrorsNoThrow(textDocument, deploymentTemplate);
                    if (isNewlyOpened) {
                        // Telemetry for template opened
                        if (errorsWarnings) {
                            this.reportAllTemplateOpenedTelemetryNoThrow(textDocument, deploymentTemplate, stopwatch, errorsWarnings);
                        }

                        // No guarantee that active editor is the one we're processing, ignore if not
                        if (editor && editor.document === textDocument) {
                            // Are they using an older schema?  Ask to update.
                            // tslint:disable-next-line: no-suspicious-comment
                            // TODO: Move to separate file
                            this.considerQueryingForNewerSchema(editor, deploymentTemplate);

                            // Is there a possibly-matching params file they might want to associate?
                            considerQueryingForParameterFileInBackground(this._mapping, textDocument);
                        }
                    }
                }
            }

            if (!treatAsDeploymentTemplate) {
                // Is it a parameter file?
                let shouldParseParameterFile = treatAsDeploymentTemplate || mightBeDeploymentParameters(textDocument);
                if (shouldParseParameterFile) {
                    // Do a full parse
                    let deploymentParameters: DeploymentParametersDoc = new DeploymentParametersDoc(textDocument.getText(), textDocument.uri, textDocument.version);
                    if (deploymentParameters.hasParametersSchema()) {
                        treatAsDeploymentParameters = true;
                    }

                    // This could theoretically include time for parsing for a deployment template as well but isn't likely
                    actionContext.telemetry.measurements.parseDurationInMilliseconds = stopwatch.duration.totalMilliseconds;

                    if (treatAsDeploymentParameters) {
                        this.ensureDeploymentDocumentEventsHookedUp();
                        this.setOpenedDeploymentDocument(documentUri, deploymentParameters);
                        this.registerActiveUse();

                        this.reportDeploymentParametersErrorsNoThrow(textDocument, deploymentParameters).then(async (errorsWarnings) => {
                            if (isNewlyOpened && errorsWarnings) {
                                // A deployment template has been opened (as opposed to having been tabbed to)

                                // Telemetry for parameter file opened
                                this.reportParameterFileOpenedTelemetry(textDocument, deploymentParameters, stopwatch, errorsWarnings);
                            }
                        }).catch(err => {
                            assert.fail("reportDeploymentParametersErrorsNoThrow failed");
                        });
                    }
                }
            }

            if (!treatAsDeploymentTemplate && !treatAsDeploymentParameters) {
                // If the document is not a deployment file, then we need
                // to remove it from our deployment file cache. It doesn't
                // matter if the document is a JSON file and was never a
                // deployment file, or if the document was a deployment
                // file and then was modified to no longer be a deployment
                // file (the $schema property changed to not be a
                // template/params schema). In either case, we should
                // remove it from our cache.
                this.closeDeploymentFile(textDocument);
            }

            this.updateEditorStateInBackground();
        });
    }