From 8a97cbb47d7020d12ac52df3747e9e28449acc8e Mon Sep 17 00:00:00 2001 From: Martin Aeschlimann Date: Wed, 6 May 2020 18:58:51 +0200 Subject: [PATCH] [json] Add setting to disable downloading JSON schemas. Fixes #96083 --- .../client/src/jsonMain.ts | 104 +++++++++++------- .../json-language-features/package.json | 8 +- .../json-language-features/package.nls.json | 3 +- 3 files changed, 76 insertions(+), 39 deletions(-) diff --git a/extensions/json-language-features/client/src/jsonMain.ts b/extensions/json-language-features/client/src/jsonMain.ts index 56f876ba373..3faf0d19630 100644 --- a/extensions/json-language-features/client/src/jsonMain.ts +++ b/extensions/json-language-features/client/src/jsonMain.ts @@ -77,6 +77,12 @@ interface JSONSchemaSettings { schema?: any; } +namespace SettingIds { + export const enableFormatter = 'json.format.enable'; + export const enableSchemaDownload = 'json.schemaDownload.enable'; + export const maxItemsComputed = 'json.maxItemsComputed'; +} + let telemetryReporter: TelemetryReporter | undefined; export function activate(context: ExtensionContext) { @@ -107,10 +113,8 @@ export function activate(context: ExtensionContext) { id: 'status.json.resolveError', name: localize('json.resolveError', "JSON: Schema Resolution Error"), alignment: StatusBarAlignment.Right, - priority: 0 + priority: 0, }); - schemaResolutionErrorStatusBarItem.command = '_json.retryResolveSchema'; - schemaResolutionErrorStatusBarItem.tooltip = localize('json.schemaResolutionErrorMessage', 'Unable to resolve schema.') + ' ' + localize('json.clickToRetry', 'Click to retry.'); schemaResolutionErrorStatusBarItem.text = '$(alert)'; toDispose.push(schemaResolutionErrorStatusBarItem); @@ -200,6 +204,7 @@ export function activate(context: ExtensionContext) { toDispose.push(disposable); client.onReady().then(() => { const schemaDocuments: { [uri: string]: boolean } = {}; + let schemaDownloadEnabled = true; // handle content request client.onRequest(VSCodeContentRequest.type, (uriPath: string) => { @@ -208,12 +213,16 @@ export function activate(context: ExtensionContext) { return Promise.reject(new Error(localize('untitled.schema', 'Unable to load {0}', uri.toString()))); } if (uri.scheme !== 'http' && uri.scheme !== 'https') { - return workspace.openTextDocument(uri).then(doc => { - schemaDocuments[uri.toString()] = true; - return doc.getText(); - }, error => { - return Promise.reject(error); - }); + if (schemaDownloadEnabled) { + return workspace.openTextDocument(uri).then(doc => { + schemaDocuments[uri.toString()] = true; + return doc.getText(); + }, error => { + return Promise.reject(error); + }); + } else { + return Promise.reject(localize('schemaDownloadDisabled', 'Downloading schemas is disabled through setting \'{0}\'', SettingIds.enableSchemaDownload)); + } } else { if (telemetryReporter && uri.authority === 'schema.management.azure.com') { /* __GDPR__ @@ -294,16 +303,61 @@ export function activate(context: ExtensionContext) { client.sendNotification(SchemaAssociationNotification.type, getSchemaAssociations(context)); }); - // manually register / deregister format provider based on the `html.format.enable` setting avoiding issues with late registration. See #71652. + // manually register / deregister format provider based on the `json.format.enable` setting avoiding issues with late registration. See #71652. updateFormatterRegistration(); toDispose.push({ dispose: () => rangeFormatting && rangeFormatting.dispose() }); - toDispose.push(workspace.onDidChangeConfiguration(e => e.affectsConfiguration('html.format.enable') && updateFormatterRegistration())); + updateSchemaDownloadSetting(); + + toDispose.push(workspace.onDidChangeConfiguration(e => { + if (e.affectsConfiguration(SettingIds.enableFormatter)) { + updateFormatterRegistration(); + } else if (e.affectsConfiguration(SettingIds.enableSchemaDownload)) { + updateSchemaDownloadSetting(); + } + })); client.onNotification(ResultLimitReachedNotification.type, message => { - window.showInformationMessage(`${message}\nUse setting 'json.maxItemsComputed' to configure the limit.`); + window.showInformationMessage(`${message}\n${localize('configureLimit', 'Use setting \'{0}\' to configure the limit.', SettingIds.maxItemsComputed)}`); }); + function updateFormatterRegistration() { + const formatEnabled = workspace.getConfiguration().get(SettingIds.enableFormatter); + if (!formatEnabled && rangeFormatting) { + rangeFormatting.dispose(); + rangeFormatting = undefined; + } else if (formatEnabled && !rangeFormatting) { + rangeFormatting = languages.registerDocumentRangeFormattingEditProvider(documentSelector, { + provideDocumentRangeFormattingEdits(document: TextDocument, range: Range, options: FormattingOptions, token: CancellationToken): ProviderResult { + const params: DocumentRangeFormattingParams = { + textDocument: client.code2ProtocolConverter.asTextDocumentIdentifier(document), + range: client.code2ProtocolConverter.asRange(range), + options: client.code2ProtocolConverter.asFormattingOptions(options) + }; + return client.sendRequest(DocumentRangeFormattingRequest.type, params, token).then( + client.protocol2CodeConverter.asTextEdits, + (error) => { + client.logFailedRequest(DocumentRangeFormattingRequest.type, error); + return Promise.resolve([]); + } + ); + } + }); + } + } + + function updateSchemaDownloadSetting() { + schemaDownloadEnabled = workspace.getConfiguration().get(SettingIds.enableSchemaDownload) !== false; + if (schemaDownloadEnabled) { + schemaResolutionErrorStatusBarItem.tooltip = localize('json.schemaResolutionErrorMessage', 'Unable to resolve schema. Click to retry.'); + schemaResolutionErrorStatusBarItem.command = '_json.retryResolveSchema'; + handleRetryResolveSchemaCommand(); + } else { + schemaResolutionErrorStatusBarItem.tooltip = localize('json.schemaResolutionDisabledMessage', 'Downloading schemas is disabled. Click to configure.'); + schemaResolutionErrorStatusBarItem.command = { command: 'workbench.action.openSettings', arguments: [SettingIds.enableSchemaDownload], title: '' }; + } + } + }); const languageConfiguration: LanguageConfiguration = { @@ -316,30 +370,6 @@ export function activate(context: ExtensionContext) { languages.setLanguageConfiguration('json', languageConfiguration); languages.setLanguageConfiguration('jsonc', languageConfiguration); - function updateFormatterRegistration() { - const formatEnabled = workspace.getConfiguration().get('json.format.enable'); - if (!formatEnabled && rangeFormatting) { - rangeFormatting.dispose(); - rangeFormatting = undefined; - } else if (formatEnabled && !rangeFormatting) { - rangeFormatting = languages.registerDocumentRangeFormattingEditProvider(documentSelector, { - provideDocumentRangeFormattingEdits(document: TextDocument, range: Range, options: FormattingOptions, token: CancellationToken): ProviderResult { - const params: DocumentRangeFormattingParams = { - textDocument: client.code2ProtocolConverter.asTextDocumentIdentifier(document), - range: client.code2ProtocolConverter.asRange(range), - options: client.code2ProtocolConverter.asFormattingOptions(options) - }; - return client.sendRequest(DocumentRangeFormattingRequest.type, params, token).then( - client.protocol2CodeConverter.asTextEdits, - (error) => { - client.logFailedRequest(DocumentRangeFormattingRequest.type, error); - return Promise.resolve([]); - } - ); - } - }); - } - } } @@ -386,7 +416,7 @@ function getSchemaAssociations(_context: ExtensionContext): ISchemaAssociation[] function getSettings(): Settings { const httpSettings = workspace.getConfiguration('http'); - const resultLimit: number = Math.trunc(Math.max(0, Number(workspace.getConfiguration().get('json.maxItemsComputed')))) || 5000; + const resultLimit: number = Math.trunc(Math.max(0, Number(workspace.getConfiguration().get(SettingIds.maxItemsComputed)))) || 5000; const settings: Settings = { http: { diff --git a/extensions/json-language-features/package.json b/extensions/json-language-features/package.json index d2edb7d54aa..2868c0c01ac 100644 --- a/extensions/json-language-features/package.json +++ b/extensions/json-language-features/package.json @@ -95,7 +95,13 @@ "type": "number", "default": 5000, "description": "%json.maxItemsComputed.desc%" - } + }, + "json.schemaDownload.enable": { + "type": "boolean", + "default": true, + "description": "%json.enableSchemaDownload.desc%", + "tags": ["usesOnlineServices"] + } } }, "configurationDefaults": { diff --git a/extensions/json-language-features/package.nls.json b/extensions/json-language-features/package.nls.json index 17bc29f9372..abf7d17b925 100644 --- a/extensions/json-language-features/package.nls.json +++ b/extensions/json-language-features/package.nls.json @@ -12,5 +12,6 @@ "json.colorDecorators.enable.deprecationMessage": "The setting `json.colorDecorators.enable` has been deprecated in favor of `editor.colorDecorators`.", "json.schemaResolutionErrorMessage": "Unable to resolve schema.", "json.clickToRetry": "Click to retry.", - "json.maxItemsComputed.desc": "The maximum number of outline symbols and folding regions computed (limited for performance reasons)." + "json.maxItemsComputed.desc": "The maximum number of outline symbols and folding regions computed (limited for performance reasons).", + "json.enableSchemaDownload.desc": "When enabled, JSON schemas can be fetched from http and https locations." }