Skip to content

Commit 8a97cbb

Browse files
committed
[json] Add setting to disable downloading JSON schemas. Fixes microsoft#96083
1 parent 9394e57 commit 8a97cbb

3 files changed

Lines changed: 76 additions & 39 deletions

File tree

extensions/json-language-features/client/src/jsonMain.ts

Lines changed: 67 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,12 @@ interface JSONSchemaSettings {
7777
schema?: any;
7878
}
7979

80+
namespace SettingIds {
81+
export const enableFormatter = 'json.format.enable';
82+
export const enableSchemaDownload = 'json.schemaDownload.enable';
83+
export const maxItemsComputed = 'json.maxItemsComputed';
84+
}
85+
8086
let telemetryReporter: TelemetryReporter | undefined;
8187

8288
export function activate(context: ExtensionContext) {
@@ -107,10 +113,8 @@ export function activate(context: ExtensionContext) {
107113
id: 'status.json.resolveError',
108114
name: localize('json.resolveError', "JSON: Schema Resolution Error"),
109115
alignment: StatusBarAlignment.Right,
110-
priority: 0
116+
priority: 0,
111117
});
112-
schemaResolutionErrorStatusBarItem.command = '_json.retryResolveSchema';
113-
schemaResolutionErrorStatusBarItem.tooltip = localize('json.schemaResolutionErrorMessage', 'Unable to resolve schema.') + ' ' + localize('json.clickToRetry', 'Click to retry.');
114118
schemaResolutionErrorStatusBarItem.text = '$(alert)';
115119
toDispose.push(schemaResolutionErrorStatusBarItem);
116120

@@ -200,6 +204,7 @@ export function activate(context: ExtensionContext) {
200204
toDispose.push(disposable);
201205
client.onReady().then(() => {
202206
const schemaDocuments: { [uri: string]: boolean } = {};
207+
let schemaDownloadEnabled = true;
203208

204209
// handle content request
205210
client.onRequest(VSCodeContentRequest.type, (uriPath: string) => {
@@ -208,12 +213,16 @@ export function activate(context: ExtensionContext) {
208213
return Promise.reject(new Error(localize('untitled.schema', 'Unable to load {0}', uri.toString())));
209214
}
210215
if (uri.scheme !== 'http' && uri.scheme !== 'https') {
211-
return workspace.openTextDocument(uri).then(doc => {
212-
schemaDocuments[uri.toString()] = true;
213-
return doc.getText();
214-
}, error => {
215-
return Promise.reject(error);
216-
});
216+
if (schemaDownloadEnabled) {
217+
return workspace.openTextDocument(uri).then(doc => {
218+
schemaDocuments[uri.toString()] = true;
219+
return doc.getText();
220+
}, error => {
221+
return Promise.reject(error);
222+
});
223+
} else {
224+
return Promise.reject(localize('schemaDownloadDisabled', 'Downloading schemas is disabled through setting \'{0}\'', SettingIds.enableSchemaDownload));
225+
}
217226
} else {
218227
if (telemetryReporter && uri.authority === 'schema.management.azure.com') {
219228
/* __GDPR__
@@ -294,16 +303,61 @@ export function activate(context: ExtensionContext) {
294303
client.sendNotification(SchemaAssociationNotification.type, getSchemaAssociations(context));
295304
});
296305

297-
// manually register / deregister format provider based on the `html.format.enable` setting avoiding issues with late registration. See #71652.
306+
// manually register / deregister format provider based on the `json.format.enable` setting avoiding issues with late registration. See #71652.
298307
updateFormatterRegistration();
299308
toDispose.push({ dispose: () => rangeFormatting && rangeFormatting.dispose() });
300-
toDispose.push(workspace.onDidChangeConfiguration(e => e.affectsConfiguration('html.format.enable') && updateFormatterRegistration()));
301309

310+
updateSchemaDownloadSetting();
311+
312+
toDispose.push(workspace.onDidChangeConfiguration(e => {
313+
if (e.affectsConfiguration(SettingIds.enableFormatter)) {
314+
updateFormatterRegistration();
315+
} else if (e.affectsConfiguration(SettingIds.enableSchemaDownload)) {
316+
updateSchemaDownloadSetting();
317+
}
318+
}));
302319

303320
client.onNotification(ResultLimitReachedNotification.type, message => {
304-
window.showInformationMessage(`${message}\nUse setting 'json.maxItemsComputed' to configure the limit.`);
321+
window.showInformationMessage(`${message}\n${localize('configureLimit', 'Use setting \'{0}\' to configure the limit.', SettingIds.maxItemsComputed)}`);
305322
});
306323

324+
function updateFormatterRegistration() {
325+
const formatEnabled = workspace.getConfiguration().get(SettingIds.enableFormatter);
326+
if (!formatEnabled && rangeFormatting) {
327+
rangeFormatting.dispose();
328+
rangeFormatting = undefined;
329+
} else if (formatEnabled && !rangeFormatting) {
330+
rangeFormatting = languages.registerDocumentRangeFormattingEditProvider(documentSelector, {
331+
provideDocumentRangeFormattingEdits(document: TextDocument, range: Range, options: FormattingOptions, token: CancellationToken): ProviderResult<TextEdit[]> {
332+
const params: DocumentRangeFormattingParams = {
333+
textDocument: client.code2ProtocolConverter.asTextDocumentIdentifier(document),
334+
range: client.code2ProtocolConverter.asRange(range),
335+
options: client.code2ProtocolConverter.asFormattingOptions(options)
336+
};
337+
return client.sendRequest(DocumentRangeFormattingRequest.type, params, token).then(
338+
client.protocol2CodeConverter.asTextEdits,
339+
(error) => {
340+
client.logFailedRequest(DocumentRangeFormattingRequest.type, error);
341+
return Promise.resolve([]);
342+
}
343+
);
344+
}
345+
});
346+
}
347+
}
348+
349+
function updateSchemaDownloadSetting() {
350+
schemaDownloadEnabled = workspace.getConfiguration().get(SettingIds.enableSchemaDownload) !== false;
351+
if (schemaDownloadEnabled) {
352+
schemaResolutionErrorStatusBarItem.tooltip = localize('json.schemaResolutionErrorMessage', 'Unable to resolve schema. Click to retry.');
353+
schemaResolutionErrorStatusBarItem.command = '_json.retryResolveSchema';
354+
handleRetryResolveSchemaCommand();
355+
} else {
356+
schemaResolutionErrorStatusBarItem.tooltip = localize('json.schemaResolutionDisabledMessage', 'Downloading schemas is disabled. Click to configure.');
357+
schemaResolutionErrorStatusBarItem.command = { command: 'workbench.action.openSettings', arguments: [SettingIds.enableSchemaDownload], title: '' };
358+
}
359+
}
360+
307361
});
308362

309363
const languageConfiguration: LanguageConfiguration = {
@@ -316,30 +370,6 @@ export function activate(context: ExtensionContext) {
316370
languages.setLanguageConfiguration('json', languageConfiguration);
317371
languages.setLanguageConfiguration('jsonc', languageConfiguration);
318372

319-
function updateFormatterRegistration() {
320-
const formatEnabled = workspace.getConfiguration().get('json.format.enable');
321-
if (!formatEnabled && rangeFormatting) {
322-
rangeFormatting.dispose();
323-
rangeFormatting = undefined;
324-
} else if (formatEnabled && !rangeFormatting) {
325-
rangeFormatting = languages.registerDocumentRangeFormattingEditProvider(documentSelector, {
326-
provideDocumentRangeFormattingEdits(document: TextDocument, range: Range, options: FormattingOptions, token: CancellationToken): ProviderResult<TextEdit[]> {
327-
const params: DocumentRangeFormattingParams = {
328-
textDocument: client.code2ProtocolConverter.asTextDocumentIdentifier(document),
329-
range: client.code2ProtocolConverter.asRange(range),
330-
options: client.code2ProtocolConverter.asFormattingOptions(options)
331-
};
332-
return client.sendRequest(DocumentRangeFormattingRequest.type, params, token).then(
333-
client.protocol2CodeConverter.asTextEdits,
334-
(error) => {
335-
client.logFailedRequest(DocumentRangeFormattingRequest.type, error);
336-
return Promise.resolve([]);
337-
}
338-
);
339-
}
340-
});
341-
}
342-
}
343373
}
344374

345375

@@ -386,7 +416,7 @@ function getSchemaAssociations(_context: ExtensionContext): ISchemaAssociation[]
386416
function getSettings(): Settings {
387417
const httpSettings = workspace.getConfiguration('http');
388418

389-
const resultLimit: number = Math.trunc(Math.max(0, Number(workspace.getConfiguration().get('json.maxItemsComputed')))) || 5000;
419+
const resultLimit: number = Math.trunc(Math.max(0, Number(workspace.getConfiguration().get(SettingIds.maxItemsComputed)))) || 5000;
390420

391421
const settings: Settings = {
392422
http: {

extensions/json-language-features/package.json

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,13 @@
9595
"type": "number",
9696
"default": 5000,
9797
"description": "%json.maxItemsComputed.desc%"
98-
}
98+
},
99+
"json.schemaDownload.enable": {
100+
"type": "boolean",
101+
"default": true,
102+
"description": "%json.enableSchemaDownload.desc%",
103+
"tags": ["usesOnlineServices"]
104+
}
99105
}
100106
},
101107
"configurationDefaults": {

extensions/json-language-features/package.nls.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,5 +12,6 @@
1212
"json.colorDecorators.enable.deprecationMessage": "The setting `json.colorDecorators.enable` has been deprecated in favor of `editor.colorDecorators`.",
1313
"json.schemaResolutionErrorMessage": "Unable to resolve schema.",
1414
"json.clickToRetry": "Click to retry.",
15-
"json.maxItemsComputed.desc": "The maximum number of outline symbols and folding regions computed (limited for performance reasons)."
15+
"json.maxItemsComputed.desc": "The maximum number of outline symbols and folding regions computed (limited for performance reasons).",
16+
"json.enableSchemaDownload.desc": "When enabled, JSON schemas can be fetched from http and https locations."
1617
}

0 commit comments

Comments
 (0)