jsonValidation.js 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. /*---------------------------------------------------------------------------------------------
  2. * Copyright (c) Microsoft Corporation. All rights reserved.
  3. * Licensed under the MIT License. See License.txt in the project root for license information.
  4. *--------------------------------------------------------------------------------------------*/
  5. import { UnresolvedSchema } from './jsonSchemaService';
  6. import { ErrorCode, Diagnostic, DiagnosticSeverity, Range } from '../jsonLanguageTypes';
  7. import * as nls from 'vscode-nls';
  8. import { isBoolean } from '../utils/objects';
  9. var localize = nls.loadMessageBundle();
  10. var JSONValidation = /** @class */ (function () {
  11. function JSONValidation(jsonSchemaService, promiseConstructor) {
  12. this.jsonSchemaService = jsonSchemaService;
  13. this.promise = promiseConstructor;
  14. this.validationEnabled = true;
  15. }
  16. JSONValidation.prototype.configure = function (raw) {
  17. if (raw) {
  18. this.validationEnabled = raw.validate !== false;
  19. this.commentSeverity = raw.allowComments ? undefined : DiagnosticSeverity.Error;
  20. }
  21. };
  22. JSONValidation.prototype.doValidation = function (textDocument, jsonDocument, documentSettings, schema) {
  23. var _this = this;
  24. if (!this.validationEnabled) {
  25. return this.promise.resolve([]);
  26. }
  27. var diagnostics = [];
  28. var added = {};
  29. var addProblem = function (problem) {
  30. // remove duplicated messages
  31. var signature = problem.range.start.line + ' ' + problem.range.start.character + ' ' + problem.message;
  32. if (!added[signature]) {
  33. added[signature] = true;
  34. diagnostics.push(problem);
  35. }
  36. };
  37. var getDiagnostics = function (schema) {
  38. var trailingCommaSeverity = (documentSettings === null || documentSettings === void 0 ? void 0 : documentSettings.trailingCommas) ? toDiagnosticSeverity(documentSettings.trailingCommas) : DiagnosticSeverity.Error;
  39. var commentSeverity = (documentSettings === null || documentSettings === void 0 ? void 0 : documentSettings.comments) ? toDiagnosticSeverity(documentSettings.comments) : _this.commentSeverity;
  40. var schemaValidation = (documentSettings === null || documentSettings === void 0 ? void 0 : documentSettings.schemaValidation) ? toDiagnosticSeverity(documentSettings.schemaValidation) : DiagnosticSeverity.Warning;
  41. var schemaRequest = (documentSettings === null || documentSettings === void 0 ? void 0 : documentSettings.schemaRequest) ? toDiagnosticSeverity(documentSettings.schemaRequest) : DiagnosticSeverity.Warning;
  42. if (schema) {
  43. if (schema.errors.length && jsonDocument.root && schemaRequest) {
  44. var astRoot = jsonDocument.root;
  45. var property = astRoot.type === 'object' ? astRoot.properties[0] : undefined;
  46. if (property && property.keyNode.value === '$schema') {
  47. var node = property.valueNode || property;
  48. var range = Range.create(textDocument.positionAt(node.offset), textDocument.positionAt(node.offset + node.length));
  49. addProblem(Diagnostic.create(range, schema.errors[0], schemaRequest, ErrorCode.SchemaResolveError));
  50. }
  51. else {
  52. var range = Range.create(textDocument.positionAt(astRoot.offset), textDocument.positionAt(astRoot.offset + 1));
  53. addProblem(Diagnostic.create(range, schema.errors[0], schemaRequest, ErrorCode.SchemaResolveError));
  54. }
  55. }
  56. else if (schemaValidation) {
  57. var semanticErrors = jsonDocument.validate(textDocument, schema.schema, schemaValidation);
  58. if (semanticErrors) {
  59. semanticErrors.forEach(addProblem);
  60. }
  61. }
  62. if (schemaAllowsComments(schema.schema)) {
  63. commentSeverity = undefined;
  64. }
  65. if (schemaAllowsTrailingCommas(schema.schema)) {
  66. trailingCommaSeverity = undefined;
  67. }
  68. }
  69. for (var _i = 0, _a = jsonDocument.syntaxErrors; _i < _a.length; _i++) {
  70. var p = _a[_i];
  71. if (p.code === ErrorCode.TrailingComma) {
  72. if (typeof trailingCommaSeverity !== 'number') {
  73. continue;
  74. }
  75. p.severity = trailingCommaSeverity;
  76. }
  77. addProblem(p);
  78. }
  79. if (typeof commentSeverity === 'number') {
  80. var message_1 = localize('InvalidCommentToken', 'Comments are not permitted in JSON.');
  81. jsonDocument.comments.forEach(function (c) {
  82. addProblem(Diagnostic.create(c, message_1, commentSeverity, ErrorCode.CommentNotPermitted));
  83. });
  84. }
  85. return diagnostics;
  86. };
  87. if (schema) {
  88. var id = schema.id || ('schemaservice://untitled/' + idCounter++);
  89. return this.jsonSchemaService.resolveSchemaContent(new UnresolvedSchema(schema), id, {}).then(function (resolvedSchema) {
  90. return getDiagnostics(resolvedSchema);
  91. });
  92. }
  93. return this.jsonSchemaService.getSchemaForResource(textDocument.uri, jsonDocument).then(function (schema) {
  94. return getDiagnostics(schema);
  95. });
  96. };
  97. return JSONValidation;
  98. }());
  99. export { JSONValidation };
  100. var idCounter = 0;
  101. function schemaAllowsComments(schemaRef) {
  102. if (schemaRef && typeof schemaRef === 'object') {
  103. if (isBoolean(schemaRef.allowComments)) {
  104. return schemaRef.allowComments;
  105. }
  106. if (schemaRef.allOf) {
  107. for (var _i = 0, _a = schemaRef.allOf; _i < _a.length; _i++) {
  108. var schema = _a[_i];
  109. var allow = schemaAllowsComments(schema);
  110. if (isBoolean(allow)) {
  111. return allow;
  112. }
  113. }
  114. }
  115. }
  116. return undefined;
  117. }
  118. function schemaAllowsTrailingCommas(schemaRef) {
  119. if (schemaRef && typeof schemaRef === 'object') {
  120. if (isBoolean(schemaRef.allowTrailingCommas)) {
  121. return schemaRef.allowTrailingCommas;
  122. }
  123. var deprSchemaRef = schemaRef;
  124. if (isBoolean(deprSchemaRef['allowsTrailingCommas'])) { // deprecated
  125. return deprSchemaRef['allowsTrailingCommas'];
  126. }
  127. if (schemaRef.allOf) {
  128. for (var _i = 0, _a = schemaRef.allOf; _i < _a.length; _i++) {
  129. var schema = _a[_i];
  130. var allow = schemaAllowsTrailingCommas(schema);
  131. if (isBoolean(allow)) {
  132. return allow;
  133. }
  134. }
  135. }
  136. }
  137. return undefined;
  138. }
  139. function toDiagnosticSeverity(severityLevel) {
  140. switch (severityLevel) {
  141. case 'error': return DiagnosticSeverity.Error;
  142. case 'warning': return DiagnosticSeverity.Warning;
  143. case 'ignore': return undefined;
  144. }
  145. return undefined;
  146. }