public doValidation()

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);
		});
	}