in src/services/jsonValidation.ts [37:114]
public doValidation(textDocument: TextDocument, jsonDocument: JSONDocument, documentSettings?: DocumentLanguageSettings, schema?: JSONSchema): Thenable<Diagnostic[]> {
if (!this.validationEnabled) {
return this.promise.resolve([]);
}
const diagnostics: Diagnostic[] = [];
const added: { [signature: string]: boolean } = {};
const addProblem = (problem: Diagnostic) => {
// remove duplicated messages
const signature = problem.range.start.line + ' ' + problem.range.start.character + ' ' + problem.message;
if (!added[signature]) {
added[signature] = true;
diagnostics.push(problem);
}
};
const getDiagnostics = (schema: ResolvedSchema | undefined) => {
let trailingCommaSeverity = documentSettings?.trailingCommas ? toDiagnosticSeverity(documentSettings.trailingCommas) : DiagnosticSeverity.Error;
let commentSeverity = documentSettings?.comments ? toDiagnosticSeverity(documentSettings.comments) : this.commentSeverity;
let schemaValidation = documentSettings?.schemaValidation ? toDiagnosticSeverity(documentSettings.schemaValidation) : DiagnosticSeverity.Warning;
let schemaRequest = documentSettings?.schemaRequest ? toDiagnosticSeverity(documentSettings.schemaRequest) : DiagnosticSeverity.Warning;
if (schema) {
if (schema.errors.length && jsonDocument.root && schemaRequest) {
const astRoot = jsonDocument.root;
const property = astRoot.type === 'object' ? astRoot.properties[0] : undefined;
if (property && property.keyNode.value === '$schema') {
const node = property.valueNode || property;
const range = Range.create(textDocument.positionAt(node.offset), textDocument.positionAt(node.offset + node.length));
addProblem(Diagnostic.create(range, schema.errors[0], schemaRequest, ErrorCode.SchemaResolveError));
} else {
const range = Range.create(textDocument.positionAt(astRoot.offset), textDocument.positionAt(astRoot.offset + 1));
addProblem(Diagnostic.create(range, schema.errors[0], schemaRequest, ErrorCode.SchemaResolveError));
}
} else if (schemaValidation) {
const semanticErrors = jsonDocument.validate(textDocument, schema.schema, schemaValidation);
if (semanticErrors) {
semanticErrors.forEach(addProblem);
}
}
if (schemaAllowsComments(schema.schema)) {
commentSeverity = undefined;
}
if (schemaAllowsTrailingCommas(schema.schema)) {
trailingCommaSeverity = undefined;
}
}
for (const p of jsonDocument.syntaxErrors) {
if (p.code === ErrorCode.TrailingComma) {
if (typeof trailingCommaSeverity !== 'number') {
continue;
}
p.severity = trailingCommaSeverity;
}
addProblem(p);
}
if (typeof commentSeverity === 'number') {
const message = localize('InvalidCommentToken', 'Comments are not permitted in JSON.');
jsonDocument.comments.forEach(c => {
addProblem(Diagnostic.create(c, message, commentSeverity, ErrorCode.CommentNotPermitted));
});
}
return diagnostics;
};
if (schema) {
const id = schema.id || ('schemaservice://untitled/' + idCounter++);
const handle = this.jsonSchemaService.registerExternalSchema(id, [], schema);
return handle.getResolvedSchema().then(resolvedSchema => {
return getDiagnostics(resolvedSchema);
});
}
return this.jsonSchemaService.getSchemaForResource(textDocument.uri, jsonDocument).then(schema => {
return getDiagnostics(schema);
});
}