in language-service/src/services/yamlValidation.ts [36:167]
public doValidation(textDocument: TextDocument, yamlDocument: YAMLDocument): Thenable<Diagnostic[]> {
if(!this.validationEnabled){
return this.promise.resolve([]);
}
if (yamlDocument.documents.length === 0) {
//this is strange...
return this.promise.resolve([]);
}
if (yamlDocument.documents.length > 1) {
//The YAML parser is a little over-eager to call things different documents
// see https://github.com/Microsoft/azure-pipelines-vscode/issues/219
//so search for a specific error so that we can offer the user better guidance
for (let document of yamlDocument.documents) {
for (let docError of document.errors) {
if (docError.getMessage().includes("end of the stream or a document separator is expected")) {
const docErrorPosition : Position = textDocument.positionAt(docError.start);
const errorLine: number = (docErrorPosition.line > 0) ? docErrorPosition.line - 1 : docErrorPosition.line;
return this.promise.resolve([{
severity: DiagnosticSeverity.Error,
range: {
start: {
line: errorLine,
character: 0
},
end: {
line: errorLine + 1,
character: 0
}
},
message: localize('documentFormatError', 'Invalid YAML structure')
}]);
}
}
}
return this.promise.resolve([{
severity: DiagnosticSeverity.Error,
range: {
start: {
line: 0,
character: 0
},
end: textDocument.positionAt(textDocument.getText().length)
},
message: localize('multiDocumentError', 'Only single-document files are supported')
}]);
}
const translateSeverity = (problemSeverity: ProblemSeverity): DiagnosticSeverity => {
if (problemSeverity === ProblemSeverity.Error) {
return DiagnosticSeverity.Error;
}
if (problemSeverity == ProblemSeverity.Warning) {
return DiagnosticSeverity.Warning;
}
return DiagnosticSeverity.Hint;
};
return this.jsonSchemaService.getSchemaForResource(textDocument.uri).then(function (schema) {
var diagnostics: Diagnostic[] = [];
let jsonDocument: SingleYAMLDocument = yamlDocument.documents[0];
jsonDocument.errors.forEach(err => {
diagnostics.push({
severity: DiagnosticSeverity.Error,
range: {
start: textDocument.positionAt(err.start),
end: textDocument.positionAt(err.end)
},
message: err.getMessage()
});
});
jsonDocument.warnings.forEach(warn => {
diagnostics.push({
severity: DiagnosticSeverity.Warning,
range: {
start: textDocument.positionAt(warn.start),
end: textDocument.positionAt(warn.end)
},
message: warn.getMessage()
});
});
if (schema) {
var added: {[key:string]: boolean} = {};
const problems: IProblem[] = jsonDocument.getValidationProblems(schema.schema);
problems.forEach(function (problem: IProblem, index: number) {
const message: string = problem.getMessage();
const signature: string = '' + problem.location.start + ' ' + problem.location.end + ' ' + message
if (!added[signature]) {
added[signature] = true;
diagnostics.push({
severity: translateSeverity(problem.severity),
range: {
start: textDocument.positionAt(problem.location.start),
end: textDocument.positionAt(problem.location.end)
},
message: message
})
}
});
if(schema.errors.length > 0) {
for(let curDiagnostic of schema.errors){
diagnostics.push({
severity: DiagnosticSeverity.Error,
range: {
start: {
line: 0,
character: 0
},
end: {
line: 0,
character: 1
}
},
message: curDiagnostic
});
}
}
}
return diagnostics;
});
}