massive update, probably broken
[dotfiles/.git] / .config / coc / extensions / node_modules / coc-json / node_modules / vscode-json-languageservice / lib / umd / parser / jsonParser.js
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 var __extends = (this && this.__extends) || (function () {
6     var extendStatics = function (d, b) {
7         extendStatics = Object.setPrototypeOf ||
8             ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
9             function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
10         return extendStatics(d, b);
11     };
12     return function (d, b) {
13         if (typeof b !== "function" && b !== null)
14             throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
15         extendStatics(d, b);
16         function __() { this.constructor = d; }
17         d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
18     };
19 })();
20 (function (factory) {
21     if (typeof module === "object" && typeof module.exports === "object") {
22         var v = factory(require, exports);
23         if (v !== undefined) module.exports = v;
24     }
25     else if (typeof define === "function" && define.amd) {
26         define(["require", "exports", "jsonc-parser", "../utils/objects", "../utils/strings", "../jsonLanguageTypes", "vscode-nls"], factory);
27     }
28 })(function (require, exports) {
29     "use strict";
30     Object.defineProperty(exports, "__esModule", { value: true });
31     exports.parse = exports.JSONDocument = exports.contains = exports.getNodePath = exports.getNodeValue = exports.newJSONDocument = exports.ValidationResult = exports.EnumMatch = exports.asSchema = exports.ObjectASTNodeImpl = exports.PropertyASTNodeImpl = exports.StringASTNodeImpl = exports.NumberASTNodeImpl = exports.ArrayASTNodeImpl = exports.BooleanASTNodeImpl = exports.NullASTNodeImpl = exports.ASTNodeImpl = void 0;
32     var Json = require("jsonc-parser");
33     var objects_1 = require("../utils/objects");
34     var strings_1 = require("../utils/strings");
35     var jsonLanguageTypes_1 = require("../jsonLanguageTypes");
36     var nls = require("vscode-nls");
37     var localize = nls.loadMessageBundle();
38     var formats = {
39         'color-hex': { errorMessage: localize('colorHexFormatWarning', 'Invalid color format. Use #RGB, #RGBA, #RRGGBB or #RRGGBBAA.'), pattern: /^#([0-9A-Fa-f]{3,4}|([0-9A-Fa-f]{2}){3,4})$/ },
40         'date-time': { errorMessage: localize('dateTimeFormatWarning', 'String is not a RFC3339 date-time.'), pattern: /^(\d{4})-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])T([01][0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9]|60)(\.[0-9]+)?(Z|(\+|-)([01][0-9]|2[0-3]):([0-5][0-9]))$/i },
41         'date': { errorMessage: localize('dateFormatWarning', 'String is not a RFC3339 date.'), pattern: /^(\d{4})-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])$/i },
42         'time': { errorMessage: localize('timeFormatWarning', 'String is not a RFC3339 time.'), pattern: /^([01][0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9]|60)(\.[0-9]+)?(Z|(\+|-)([01][0-9]|2[0-3]):([0-5][0-9]))$/i },
43         'email': { errorMessage: localize('emailFormatWarning', 'String is not an e-mail address.'), pattern: /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/ }
44     };
45     var ASTNodeImpl = /** @class */ (function () {
46         function ASTNodeImpl(parent, offset, length) {
47             if (length === void 0) { length = 0; }
48             this.offset = offset;
49             this.length = length;
50             this.parent = parent;
51         }
52         Object.defineProperty(ASTNodeImpl.prototype, "children", {
53             get: function () {
54                 return [];
55             },
56             enumerable: false,
57             configurable: true
58         });
59         ASTNodeImpl.prototype.toString = function () {
60             return 'type: ' + this.type + ' (' + this.offset + '/' + this.length + ')' + (this.parent ? ' parent: {' + this.parent.toString() + '}' : '');
61         };
62         return ASTNodeImpl;
63     }());
64     exports.ASTNodeImpl = ASTNodeImpl;
65     var NullASTNodeImpl = /** @class */ (function (_super) {
66         __extends(NullASTNodeImpl, _super);
67         function NullASTNodeImpl(parent, offset) {
68             var _this = _super.call(this, parent, offset) || this;
69             _this.type = 'null';
70             _this.value = null;
71             return _this;
72         }
73         return NullASTNodeImpl;
74     }(ASTNodeImpl));
75     exports.NullASTNodeImpl = NullASTNodeImpl;
76     var BooleanASTNodeImpl = /** @class */ (function (_super) {
77         __extends(BooleanASTNodeImpl, _super);
78         function BooleanASTNodeImpl(parent, boolValue, offset) {
79             var _this = _super.call(this, parent, offset) || this;
80             _this.type = 'boolean';
81             _this.value = boolValue;
82             return _this;
83         }
84         return BooleanASTNodeImpl;
85     }(ASTNodeImpl));
86     exports.BooleanASTNodeImpl = BooleanASTNodeImpl;
87     var ArrayASTNodeImpl = /** @class */ (function (_super) {
88         __extends(ArrayASTNodeImpl, _super);
89         function ArrayASTNodeImpl(parent, offset) {
90             var _this = _super.call(this, parent, offset) || this;
91             _this.type = 'array';
92             _this.items = [];
93             return _this;
94         }
95         Object.defineProperty(ArrayASTNodeImpl.prototype, "children", {
96             get: function () {
97                 return this.items;
98             },
99             enumerable: false,
100             configurable: true
101         });
102         return ArrayASTNodeImpl;
103     }(ASTNodeImpl));
104     exports.ArrayASTNodeImpl = ArrayASTNodeImpl;
105     var NumberASTNodeImpl = /** @class */ (function (_super) {
106         __extends(NumberASTNodeImpl, _super);
107         function NumberASTNodeImpl(parent, offset) {
108             var _this = _super.call(this, parent, offset) || this;
109             _this.type = 'number';
110             _this.isInteger = true;
111             _this.value = Number.NaN;
112             return _this;
113         }
114         return NumberASTNodeImpl;
115     }(ASTNodeImpl));
116     exports.NumberASTNodeImpl = NumberASTNodeImpl;
117     var StringASTNodeImpl = /** @class */ (function (_super) {
118         __extends(StringASTNodeImpl, _super);
119         function StringASTNodeImpl(parent, offset, length) {
120             var _this = _super.call(this, parent, offset, length) || this;
121             _this.type = 'string';
122             _this.value = '';
123             return _this;
124         }
125         return StringASTNodeImpl;
126     }(ASTNodeImpl));
127     exports.StringASTNodeImpl = StringASTNodeImpl;
128     var PropertyASTNodeImpl = /** @class */ (function (_super) {
129         __extends(PropertyASTNodeImpl, _super);
130         function PropertyASTNodeImpl(parent, offset, keyNode) {
131             var _this = _super.call(this, parent, offset) || this;
132             _this.type = 'property';
133             _this.colonOffset = -1;
134             _this.keyNode = keyNode;
135             return _this;
136         }
137         Object.defineProperty(PropertyASTNodeImpl.prototype, "children", {
138             get: function () {
139                 return this.valueNode ? [this.keyNode, this.valueNode] : [this.keyNode];
140             },
141             enumerable: false,
142             configurable: true
143         });
144         return PropertyASTNodeImpl;
145     }(ASTNodeImpl));
146     exports.PropertyASTNodeImpl = PropertyASTNodeImpl;
147     var ObjectASTNodeImpl = /** @class */ (function (_super) {
148         __extends(ObjectASTNodeImpl, _super);
149         function ObjectASTNodeImpl(parent, offset) {
150             var _this = _super.call(this, parent, offset) || this;
151             _this.type = 'object';
152             _this.properties = [];
153             return _this;
154         }
155         Object.defineProperty(ObjectASTNodeImpl.prototype, "children", {
156             get: function () {
157                 return this.properties;
158             },
159             enumerable: false,
160             configurable: true
161         });
162         return ObjectASTNodeImpl;
163     }(ASTNodeImpl));
164     exports.ObjectASTNodeImpl = ObjectASTNodeImpl;
165     function asSchema(schema) {
166         if (objects_1.isBoolean(schema)) {
167             return schema ? {} : { "not": {} };
168         }
169         return schema;
170     }
171     exports.asSchema = asSchema;
172     var EnumMatch;
173     (function (EnumMatch) {
174         EnumMatch[EnumMatch["Key"] = 0] = "Key";
175         EnumMatch[EnumMatch["Enum"] = 1] = "Enum";
176     })(EnumMatch = exports.EnumMatch || (exports.EnumMatch = {}));
177     var SchemaCollector = /** @class */ (function () {
178         function SchemaCollector(focusOffset, exclude) {
179             if (focusOffset === void 0) { focusOffset = -1; }
180             this.focusOffset = focusOffset;
181             this.exclude = exclude;
182             this.schemas = [];
183         }
184         SchemaCollector.prototype.add = function (schema) {
185             this.schemas.push(schema);
186         };
187         SchemaCollector.prototype.merge = function (other) {
188             Array.prototype.push.apply(this.schemas, other.schemas);
189         };
190         SchemaCollector.prototype.include = function (node) {
191             return (this.focusOffset === -1 || contains(node, this.focusOffset)) && (node !== this.exclude);
192         };
193         SchemaCollector.prototype.newSub = function () {
194             return new SchemaCollector(-1, this.exclude);
195         };
196         return SchemaCollector;
197     }());
198     var NoOpSchemaCollector = /** @class */ (function () {
199         function NoOpSchemaCollector() {
200         }
201         Object.defineProperty(NoOpSchemaCollector.prototype, "schemas", {
202             get: function () { return []; },
203             enumerable: false,
204             configurable: true
205         });
206         NoOpSchemaCollector.prototype.add = function (schema) { };
207         NoOpSchemaCollector.prototype.merge = function (other) { };
208         NoOpSchemaCollector.prototype.include = function (node) { return true; };
209         NoOpSchemaCollector.prototype.newSub = function () { return this; };
210         NoOpSchemaCollector.instance = new NoOpSchemaCollector();
211         return NoOpSchemaCollector;
212     }());
213     var ValidationResult = /** @class */ (function () {
214         function ValidationResult() {
215             this.problems = [];
216             this.propertiesMatches = 0;
217             this.propertiesValueMatches = 0;
218             this.primaryValueMatches = 0;
219             this.enumValueMatch = false;
220             this.enumValues = undefined;
221         }
222         ValidationResult.prototype.hasProblems = function () {
223             return !!this.problems.length;
224         };
225         ValidationResult.prototype.mergeAll = function (validationResults) {
226             for (var _i = 0, validationResults_1 = validationResults; _i < validationResults_1.length; _i++) {
227                 var validationResult = validationResults_1[_i];
228                 this.merge(validationResult);
229             }
230         };
231         ValidationResult.prototype.merge = function (validationResult) {
232             this.problems = this.problems.concat(validationResult.problems);
233         };
234         ValidationResult.prototype.mergeEnumValues = function (validationResult) {
235             if (!this.enumValueMatch && !validationResult.enumValueMatch && this.enumValues && validationResult.enumValues) {
236                 this.enumValues = this.enumValues.concat(validationResult.enumValues);
237                 for (var _i = 0, _a = this.problems; _i < _a.length; _i++) {
238                     var error = _a[_i];
239                     if (error.code === jsonLanguageTypes_1.ErrorCode.EnumValueMismatch) {
240                         error.message = localize('enumWarning', 'Value is not accepted. Valid values: {0}.', this.enumValues.map(function (v) { return JSON.stringify(v); }).join(', '));
241                     }
242                 }
243             }
244         };
245         ValidationResult.prototype.mergePropertyMatch = function (propertyValidationResult) {
246             this.merge(propertyValidationResult);
247             this.propertiesMatches++;
248             if (propertyValidationResult.enumValueMatch || !propertyValidationResult.hasProblems() && propertyValidationResult.propertiesMatches) {
249                 this.propertiesValueMatches++;
250             }
251             if (propertyValidationResult.enumValueMatch && propertyValidationResult.enumValues && propertyValidationResult.enumValues.length === 1) {
252                 this.primaryValueMatches++;
253             }
254         };
255         ValidationResult.prototype.compare = function (other) {
256             var hasProblems = this.hasProblems();
257             if (hasProblems !== other.hasProblems()) {
258                 return hasProblems ? -1 : 1;
259             }
260             if (this.enumValueMatch !== other.enumValueMatch) {
261                 return other.enumValueMatch ? -1 : 1;
262             }
263             if (this.primaryValueMatches !== other.primaryValueMatches) {
264                 return this.primaryValueMatches - other.primaryValueMatches;
265             }
266             if (this.propertiesValueMatches !== other.propertiesValueMatches) {
267                 return this.propertiesValueMatches - other.propertiesValueMatches;
268             }
269             return this.propertiesMatches - other.propertiesMatches;
270         };
271         return ValidationResult;
272     }());
273     exports.ValidationResult = ValidationResult;
274     function newJSONDocument(root, diagnostics) {
275         if (diagnostics === void 0) { diagnostics = []; }
276         return new JSONDocument(root, diagnostics, []);
277     }
278     exports.newJSONDocument = newJSONDocument;
279     function getNodeValue(node) {
280         return Json.getNodeValue(node);
281     }
282     exports.getNodeValue = getNodeValue;
283     function getNodePath(node) {
284         return Json.getNodePath(node);
285     }
286     exports.getNodePath = getNodePath;
287     function contains(node, offset, includeRightBound) {
288         if (includeRightBound === void 0) { includeRightBound = false; }
289         return offset >= node.offset && offset < (node.offset + node.length) || includeRightBound && offset === (node.offset + node.length);
290     }
291     exports.contains = contains;
292     var JSONDocument = /** @class */ (function () {
293         function JSONDocument(root, syntaxErrors, comments) {
294             if (syntaxErrors === void 0) { syntaxErrors = []; }
295             if (comments === void 0) { comments = []; }
296             this.root = root;
297             this.syntaxErrors = syntaxErrors;
298             this.comments = comments;
299         }
300         JSONDocument.prototype.getNodeFromOffset = function (offset, includeRightBound) {
301             if (includeRightBound === void 0) { includeRightBound = false; }
302             if (this.root) {
303                 return Json.findNodeAtOffset(this.root, offset, includeRightBound);
304             }
305             return undefined;
306         };
307         JSONDocument.prototype.visit = function (visitor) {
308             if (this.root) {
309                 var doVisit_1 = function (node) {
310                     var ctn = visitor(node);
311                     var children = node.children;
312                     if (Array.isArray(children)) {
313                         for (var i = 0; i < children.length && ctn; i++) {
314                             ctn = doVisit_1(children[i]);
315                         }
316                     }
317                     return ctn;
318                 };
319                 doVisit_1(this.root);
320             }
321         };
322         JSONDocument.prototype.validate = function (textDocument, schema, severity) {
323             if (severity === void 0) { severity = jsonLanguageTypes_1.DiagnosticSeverity.Warning; }
324             if (this.root && schema) {
325                 var validationResult = new ValidationResult();
326                 validate(this.root, schema, validationResult, NoOpSchemaCollector.instance);
327                 return validationResult.problems.map(function (p) {
328                     var _a;
329                     var range = jsonLanguageTypes_1.Range.create(textDocument.positionAt(p.location.offset), textDocument.positionAt(p.location.offset + p.location.length));
330                     return jsonLanguageTypes_1.Diagnostic.create(range, p.message, (_a = p.severity) !== null && _a !== void 0 ? _a : severity, p.code);
331                 });
332             }
333             return undefined;
334         };
335         JSONDocument.prototype.getMatchingSchemas = function (schema, focusOffset, exclude) {
336             if (focusOffset === void 0) { focusOffset = -1; }
337             var matchingSchemas = new SchemaCollector(focusOffset, exclude);
338             if (this.root && schema) {
339                 validate(this.root, schema, new ValidationResult(), matchingSchemas);
340             }
341             return matchingSchemas.schemas;
342         };
343         return JSONDocument;
344     }());
345     exports.JSONDocument = JSONDocument;
346     function validate(n, schema, validationResult, matchingSchemas) {
347         if (!n || !matchingSchemas.include(n)) {
348             return;
349         }
350         var node = n;
351         switch (node.type) {
352             case 'object':
353                 _validateObjectNode(node, schema, validationResult, matchingSchemas);
354                 break;
355             case 'array':
356                 _validateArrayNode(node, schema, validationResult, matchingSchemas);
357                 break;
358             case 'string':
359                 _validateStringNode(node, schema, validationResult, matchingSchemas);
360                 break;
361             case 'number':
362                 _validateNumberNode(node, schema, validationResult, matchingSchemas);
363                 break;
364             case 'property':
365                 return validate(node.valueNode, schema, validationResult, matchingSchemas);
366         }
367         _validateNode();
368         matchingSchemas.add({ node: node, schema: schema });
369         function _validateNode() {
370             function matchesType(type) {
371                 return node.type === type || (type === 'integer' && node.type === 'number' && node.isInteger);
372             }
373             if (Array.isArray(schema.type)) {
374                 if (!schema.type.some(matchesType)) {
375                     validationResult.problems.push({
376                         location: { offset: node.offset, length: node.length },
377                         message: schema.errorMessage || localize('typeArrayMismatchWarning', 'Incorrect type. Expected one of {0}.', schema.type.join(', '))
378                     });
379                 }
380             }
381             else if (schema.type) {
382                 if (!matchesType(schema.type)) {
383                     validationResult.problems.push({
384                         location: { offset: node.offset, length: node.length },
385                         message: schema.errorMessage || localize('typeMismatchWarning', 'Incorrect type. Expected "{0}".', schema.type)
386                     });
387                 }
388             }
389             if (Array.isArray(schema.allOf)) {
390                 for (var _i = 0, _a = schema.allOf; _i < _a.length; _i++) {
391                     var subSchemaRef = _a[_i];
392                     validate(node, asSchema(subSchemaRef), validationResult, matchingSchemas);
393                 }
394             }
395             var notSchema = asSchema(schema.not);
396             if (notSchema) {
397                 var subValidationResult = new ValidationResult();
398                 var subMatchingSchemas = matchingSchemas.newSub();
399                 validate(node, notSchema, subValidationResult, subMatchingSchemas);
400                 if (!subValidationResult.hasProblems()) {
401                     validationResult.problems.push({
402                         location: { offset: node.offset, length: node.length },
403                         message: localize('notSchemaWarning', "Matches a schema that is not allowed.")
404                     });
405                 }
406                 for (var _b = 0, _c = subMatchingSchemas.schemas; _b < _c.length; _b++) {
407                     var ms = _c[_b];
408                     ms.inverted = !ms.inverted;
409                     matchingSchemas.add(ms);
410                 }
411             }
412             var testAlternatives = function (alternatives, maxOneMatch) {
413                 var matches = [];
414                 // remember the best match that is used for error messages
415                 var bestMatch = undefined;
416                 for (var _i = 0, alternatives_1 = alternatives; _i < alternatives_1.length; _i++) {
417                     var subSchemaRef = alternatives_1[_i];
418                     var subSchema = asSchema(subSchemaRef);
419                     var subValidationResult = new ValidationResult();
420                     var subMatchingSchemas = matchingSchemas.newSub();
421                     validate(node, subSchema, subValidationResult, subMatchingSchemas);
422                     if (!subValidationResult.hasProblems()) {
423                         matches.push(subSchema);
424                     }
425                     if (!bestMatch) {
426                         bestMatch = { schema: subSchema, validationResult: subValidationResult, matchingSchemas: subMatchingSchemas };
427                     }
428                     else {
429                         if (!maxOneMatch && !subValidationResult.hasProblems() && !bestMatch.validationResult.hasProblems()) {
430                             // no errors, both are equally good matches
431                             bestMatch.matchingSchemas.merge(subMatchingSchemas);
432                             bestMatch.validationResult.propertiesMatches += subValidationResult.propertiesMatches;
433                             bestMatch.validationResult.propertiesValueMatches += subValidationResult.propertiesValueMatches;
434                         }
435                         else {
436                             var compareResult = subValidationResult.compare(bestMatch.validationResult);
437                             if (compareResult > 0) {
438                                 // our node is the best matching so far
439                                 bestMatch = { schema: subSchema, validationResult: subValidationResult, matchingSchemas: subMatchingSchemas };
440                             }
441                             else if (compareResult === 0) {
442                                 // there's already a best matching but we are as good
443                                 bestMatch.matchingSchemas.merge(subMatchingSchemas);
444                                 bestMatch.validationResult.mergeEnumValues(subValidationResult);
445                             }
446                         }
447                     }
448                 }
449                 if (matches.length > 1 && maxOneMatch) {
450                     validationResult.problems.push({
451                         location: { offset: node.offset, length: 1 },
452                         message: localize('oneOfWarning', "Matches multiple schemas when only one must validate.")
453                     });
454                 }
455                 if (bestMatch) {
456                     validationResult.merge(bestMatch.validationResult);
457                     validationResult.propertiesMatches += bestMatch.validationResult.propertiesMatches;
458                     validationResult.propertiesValueMatches += bestMatch.validationResult.propertiesValueMatches;
459                     matchingSchemas.merge(bestMatch.matchingSchemas);
460                 }
461                 return matches.length;
462             };
463             if (Array.isArray(schema.anyOf)) {
464                 testAlternatives(schema.anyOf, false);
465             }
466             if (Array.isArray(schema.oneOf)) {
467                 testAlternatives(schema.oneOf, true);
468             }
469             var testBranch = function (schema) {
470                 var subValidationResult = new ValidationResult();
471                 var subMatchingSchemas = matchingSchemas.newSub();
472                 validate(node, asSchema(schema), subValidationResult, subMatchingSchemas);
473                 validationResult.merge(subValidationResult);
474                 validationResult.propertiesMatches += subValidationResult.propertiesMatches;
475                 validationResult.propertiesValueMatches += subValidationResult.propertiesValueMatches;
476                 matchingSchemas.merge(subMatchingSchemas);
477             };
478             var testCondition = function (ifSchema, thenSchema, elseSchema) {
479                 var subSchema = asSchema(ifSchema);
480                 var subValidationResult = new ValidationResult();
481                 var subMatchingSchemas = matchingSchemas.newSub();
482                 validate(node, subSchema, subValidationResult, subMatchingSchemas);
483                 matchingSchemas.merge(subMatchingSchemas);
484                 if (!subValidationResult.hasProblems()) {
485                     if (thenSchema) {
486                         testBranch(thenSchema);
487                     }
488                 }
489                 else if (elseSchema) {
490                     testBranch(elseSchema);
491                 }
492             };
493             var ifSchema = asSchema(schema.if);
494             if (ifSchema) {
495                 testCondition(ifSchema, asSchema(schema.then), asSchema(schema.else));
496             }
497             if (Array.isArray(schema.enum)) {
498                 var val = getNodeValue(node);
499                 var enumValueMatch = false;
500                 for (var _d = 0, _e = schema.enum; _d < _e.length; _d++) {
501                     var e = _e[_d];
502                     if (objects_1.equals(val, e)) {
503                         enumValueMatch = true;
504                         break;
505                     }
506                 }
507                 validationResult.enumValues = schema.enum;
508                 validationResult.enumValueMatch = enumValueMatch;
509                 if (!enumValueMatch) {
510                     validationResult.problems.push({
511                         location: { offset: node.offset, length: node.length },
512                         code: jsonLanguageTypes_1.ErrorCode.EnumValueMismatch,
513                         message: schema.errorMessage || localize('enumWarning', 'Value is not accepted. Valid values: {0}.', schema.enum.map(function (v) { return JSON.stringify(v); }).join(', '))
514                     });
515                 }
516             }
517             if (objects_1.isDefined(schema.const)) {
518                 var val = getNodeValue(node);
519                 if (!objects_1.equals(val, schema.const)) {
520                     validationResult.problems.push({
521                         location: { offset: node.offset, length: node.length },
522                         code: jsonLanguageTypes_1.ErrorCode.EnumValueMismatch,
523                         message: schema.errorMessage || localize('constWarning', 'Value must be {0}.', JSON.stringify(schema.const))
524                     });
525                     validationResult.enumValueMatch = false;
526                 }
527                 else {
528                     validationResult.enumValueMatch = true;
529                 }
530                 validationResult.enumValues = [schema.const];
531             }
532             if (schema.deprecationMessage && node.parent) {
533                 validationResult.problems.push({
534                     location: { offset: node.parent.offset, length: node.parent.length },
535                     severity: jsonLanguageTypes_1.DiagnosticSeverity.Warning,
536                     message: schema.deprecationMessage,
537                     code: jsonLanguageTypes_1.ErrorCode.Deprecated
538                 });
539             }
540         }
541         function _validateNumberNode(node, schema, validationResult, matchingSchemas) {
542             var val = node.value;
543             function normalizeFloats(float) {
544                 var _a;
545                 var parts = /^(-?\d+)(?:\.(\d+))?(?:e([-+]\d+))?$/.exec(float.toString());
546                 return parts && {
547                     value: Number(parts[1] + (parts[2] || '')),
548                     multiplier: (((_a = parts[2]) === null || _a === void 0 ? void 0 : _a.length) || 0) - (parseInt(parts[3]) || 0)
549                 };
550             }
551             ;
552             if (objects_1.isNumber(schema.multipleOf)) {
553                 var remainder = -1;
554                 if (Number.isInteger(schema.multipleOf)) {
555                     remainder = val % schema.multipleOf;
556                 }
557                 else {
558                     var normMultipleOf = normalizeFloats(schema.multipleOf);
559                     var normValue = normalizeFloats(val);
560                     if (normMultipleOf && normValue) {
561                         var multiplier = Math.pow(10, Math.abs(normValue.multiplier - normMultipleOf.multiplier));
562                         if (normValue.multiplier < normMultipleOf.multiplier) {
563                             normValue.value *= multiplier;
564                         }
565                         else {
566                             normMultipleOf.value *= multiplier;
567                         }
568                         remainder = normValue.value % normMultipleOf.value;
569                     }
570                 }
571                 if (remainder !== 0) {
572                     validationResult.problems.push({
573                         location: { offset: node.offset, length: node.length },
574                         message: localize('multipleOfWarning', 'Value is not divisible by {0}.', schema.multipleOf)
575                     });
576                 }
577             }
578             function getExclusiveLimit(limit, exclusive) {
579                 if (objects_1.isNumber(exclusive)) {
580                     return exclusive;
581                 }
582                 if (objects_1.isBoolean(exclusive) && exclusive) {
583                     return limit;
584                 }
585                 return undefined;
586             }
587             function getLimit(limit, exclusive) {
588                 if (!objects_1.isBoolean(exclusive) || !exclusive) {
589                     return limit;
590                 }
591                 return undefined;
592             }
593             var exclusiveMinimum = getExclusiveLimit(schema.minimum, schema.exclusiveMinimum);
594             if (objects_1.isNumber(exclusiveMinimum) && val <= exclusiveMinimum) {
595                 validationResult.problems.push({
596                     location: { offset: node.offset, length: node.length },
597                     message: localize('exclusiveMinimumWarning', 'Value is below the exclusive minimum of {0}.', exclusiveMinimum)
598                 });
599             }
600             var exclusiveMaximum = getExclusiveLimit(schema.maximum, schema.exclusiveMaximum);
601             if (objects_1.isNumber(exclusiveMaximum) && val >= exclusiveMaximum) {
602                 validationResult.problems.push({
603                     location: { offset: node.offset, length: node.length },
604                     message: localize('exclusiveMaximumWarning', 'Value is above the exclusive maximum of {0}.', exclusiveMaximum)
605                 });
606             }
607             var minimum = getLimit(schema.minimum, schema.exclusiveMinimum);
608             if (objects_1.isNumber(minimum) && val < minimum) {
609                 validationResult.problems.push({
610                     location: { offset: node.offset, length: node.length },
611                     message: localize('minimumWarning', 'Value is below the minimum of {0}.', minimum)
612                 });
613             }
614             var maximum = getLimit(schema.maximum, schema.exclusiveMaximum);
615             if (objects_1.isNumber(maximum) && val > maximum) {
616                 validationResult.problems.push({
617                     location: { offset: node.offset, length: node.length },
618                     message: localize('maximumWarning', 'Value is above the maximum of {0}.', maximum)
619                 });
620             }
621         }
622         function _validateStringNode(node, schema, validationResult, matchingSchemas) {
623             if (objects_1.isNumber(schema.minLength) && node.value.length < schema.minLength) {
624                 validationResult.problems.push({
625                     location: { offset: node.offset, length: node.length },
626                     message: localize('minLengthWarning', 'String is shorter than the minimum length of {0}.', schema.minLength)
627                 });
628             }
629             if (objects_1.isNumber(schema.maxLength) && node.value.length > schema.maxLength) {
630                 validationResult.problems.push({
631                     location: { offset: node.offset, length: node.length },
632                     message: localize('maxLengthWarning', 'String is longer than the maximum length of {0}.', schema.maxLength)
633                 });
634             }
635             if (objects_1.isString(schema.pattern)) {
636                 var regex = strings_1.extendedRegExp(schema.pattern);
637                 if (!regex.test(node.value)) {
638                     validationResult.problems.push({
639                         location: { offset: node.offset, length: node.length },
640                         message: schema.patternErrorMessage || schema.errorMessage || localize('patternWarning', 'String does not match the pattern of "{0}".', schema.pattern)
641                     });
642                 }
643             }
644             if (schema.format) {
645                 switch (schema.format) {
646                     case 'uri':
647                     case 'uri-reference':
648                         {
649                             var errorMessage = void 0;
650                             if (!node.value) {
651                                 errorMessage = localize('uriEmpty', 'URI expected.');
652                             }
653                             else {
654                                 var match = /^(([^:/?#]+?):)?(\/\/([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?/.exec(node.value);
655                                 if (!match) {
656                                     errorMessage = localize('uriMissing', 'URI is expected.');
657                                 }
658                                 else if (!match[2] && schema.format === 'uri') {
659                                     errorMessage = localize('uriSchemeMissing', 'URI with a scheme is expected.');
660                                 }
661                             }
662                             if (errorMessage) {
663                                 validationResult.problems.push({
664                                     location: { offset: node.offset, length: node.length },
665                                     message: schema.patternErrorMessage || schema.errorMessage || localize('uriFormatWarning', 'String is not a URI: {0}', errorMessage)
666                                 });
667                             }
668                         }
669                         break;
670                     case 'color-hex':
671                     case 'date-time':
672                     case 'date':
673                     case 'time':
674                     case 'email':
675                         var format = formats[schema.format];
676                         if (!node.value || !format.pattern.exec(node.value)) {
677                             validationResult.problems.push({
678                                 location: { offset: node.offset, length: node.length },
679                                 message: schema.patternErrorMessage || schema.errorMessage || format.errorMessage
680                             });
681                         }
682                     default:
683                 }
684             }
685         }
686         function _validateArrayNode(node, schema, validationResult, matchingSchemas) {
687             if (Array.isArray(schema.items)) {
688                 var subSchemas = schema.items;
689                 for (var index = 0; index < subSchemas.length; index++) {
690                     var subSchemaRef = subSchemas[index];
691                     var subSchema = asSchema(subSchemaRef);
692                     var itemValidationResult = new ValidationResult();
693                     var item = node.items[index];
694                     if (item) {
695                         validate(item, subSchema, itemValidationResult, matchingSchemas);
696                         validationResult.mergePropertyMatch(itemValidationResult);
697                     }
698                     else if (node.items.length >= subSchemas.length) {
699                         validationResult.propertiesValueMatches++;
700                     }
701                 }
702                 if (node.items.length > subSchemas.length) {
703                     if (typeof schema.additionalItems === 'object') {
704                         for (var i = subSchemas.length; i < node.items.length; i++) {
705                             var itemValidationResult = new ValidationResult();
706                             validate(node.items[i], schema.additionalItems, itemValidationResult, matchingSchemas);
707                             validationResult.mergePropertyMatch(itemValidationResult);
708                         }
709                     }
710                     else if (schema.additionalItems === false) {
711                         validationResult.problems.push({
712                             location: { offset: node.offset, length: node.length },
713                             message: localize('additionalItemsWarning', 'Array has too many items according to schema. Expected {0} or fewer.', subSchemas.length)
714                         });
715                     }
716                 }
717             }
718             else {
719                 var itemSchema = asSchema(schema.items);
720                 if (itemSchema) {
721                     for (var _i = 0, _a = node.items; _i < _a.length; _i++) {
722                         var item = _a[_i];
723                         var itemValidationResult = new ValidationResult();
724                         validate(item, itemSchema, itemValidationResult, matchingSchemas);
725                         validationResult.mergePropertyMatch(itemValidationResult);
726                     }
727                 }
728             }
729             var containsSchema = asSchema(schema.contains);
730             if (containsSchema) {
731                 var doesContain = node.items.some(function (item) {
732                     var itemValidationResult = new ValidationResult();
733                     validate(item, containsSchema, itemValidationResult, NoOpSchemaCollector.instance);
734                     return !itemValidationResult.hasProblems();
735                 });
736                 if (!doesContain) {
737                     validationResult.problems.push({
738                         location: { offset: node.offset, length: node.length },
739                         message: schema.errorMessage || localize('requiredItemMissingWarning', 'Array does not contain required item.')
740                     });
741                 }
742             }
743             if (objects_1.isNumber(schema.minItems) && node.items.length < schema.minItems) {
744                 validationResult.problems.push({
745                     location: { offset: node.offset, length: node.length },
746                     message: localize('minItemsWarning', 'Array has too few items. Expected {0} or more.', schema.minItems)
747                 });
748             }
749             if (objects_1.isNumber(schema.maxItems) && node.items.length > schema.maxItems) {
750                 validationResult.problems.push({
751                     location: { offset: node.offset, length: node.length },
752                     message: localize('maxItemsWarning', 'Array has too many items. Expected {0} or fewer.', schema.maxItems)
753                 });
754             }
755             if (schema.uniqueItems === true) {
756                 var values_1 = getNodeValue(node);
757                 var duplicates = values_1.some(function (value, index) {
758                     return index !== values_1.lastIndexOf(value);
759                 });
760                 if (duplicates) {
761                     validationResult.problems.push({
762                         location: { offset: node.offset, length: node.length },
763                         message: localize('uniqueItemsWarning', 'Array has duplicate items.')
764                     });
765                 }
766             }
767         }
768         function _validateObjectNode(node, schema, validationResult, matchingSchemas) {
769             var seenKeys = Object.create(null);
770             var unprocessedProperties = [];
771             for (var _i = 0, _a = node.properties; _i < _a.length; _i++) {
772                 var propertyNode = _a[_i];
773                 var key = propertyNode.keyNode.value;
774                 seenKeys[key] = propertyNode.valueNode;
775                 unprocessedProperties.push(key);
776             }
777             if (Array.isArray(schema.required)) {
778                 for (var _b = 0, _c = schema.required; _b < _c.length; _b++) {
779                     var propertyName = _c[_b];
780                     if (!seenKeys[propertyName]) {
781                         var keyNode = node.parent && node.parent.type === 'property' && node.parent.keyNode;
782                         var location = keyNode ? { offset: keyNode.offset, length: keyNode.length } : { offset: node.offset, length: 1 };
783                         validationResult.problems.push({
784                             location: location,
785                             message: localize('MissingRequiredPropWarning', 'Missing property "{0}".', propertyName)
786                         });
787                     }
788                 }
789             }
790             var propertyProcessed = function (prop) {
791                 var index = unprocessedProperties.indexOf(prop);
792                 while (index >= 0) {
793                     unprocessedProperties.splice(index, 1);
794                     index = unprocessedProperties.indexOf(prop);
795                 }
796             };
797             if (schema.properties) {
798                 for (var _d = 0, _e = Object.keys(schema.properties); _d < _e.length; _d++) {
799                     var propertyName = _e[_d];
800                     propertyProcessed(propertyName);
801                     var propertySchema = schema.properties[propertyName];
802                     var child = seenKeys[propertyName];
803                     if (child) {
804                         if (objects_1.isBoolean(propertySchema)) {
805                             if (!propertySchema) {
806                                 var propertyNode = child.parent;
807                                 validationResult.problems.push({
808                                     location: { offset: propertyNode.keyNode.offset, length: propertyNode.keyNode.length },
809                                     message: schema.errorMessage || localize('DisallowedExtraPropWarning', 'Property {0} is not allowed.', propertyName)
810                                 });
811                             }
812                             else {
813                                 validationResult.propertiesMatches++;
814                                 validationResult.propertiesValueMatches++;
815                             }
816                         }
817                         else {
818                             var propertyValidationResult = new ValidationResult();
819                             validate(child, propertySchema, propertyValidationResult, matchingSchemas);
820                             validationResult.mergePropertyMatch(propertyValidationResult);
821                         }
822                     }
823                 }
824             }
825             if (schema.patternProperties) {
826                 for (var _f = 0, _g = Object.keys(schema.patternProperties); _f < _g.length; _f++) {
827                     var propertyPattern = _g[_f];
828                     var regex = strings_1.extendedRegExp(propertyPattern);
829                     for (var _h = 0, _j = unprocessedProperties.slice(0); _h < _j.length; _h++) {
830                         var propertyName = _j[_h];
831                         if (regex.test(propertyName)) {
832                             propertyProcessed(propertyName);
833                             var child = seenKeys[propertyName];
834                             if (child) {
835                                 var propertySchema = schema.patternProperties[propertyPattern];
836                                 if (objects_1.isBoolean(propertySchema)) {
837                                     if (!propertySchema) {
838                                         var propertyNode = child.parent;
839                                         validationResult.problems.push({
840                                             location: { offset: propertyNode.keyNode.offset, length: propertyNode.keyNode.length },
841                                             message: schema.errorMessage || localize('DisallowedExtraPropWarning', 'Property {0} is not allowed.', propertyName)
842                                         });
843                                     }
844                                     else {
845                                         validationResult.propertiesMatches++;
846                                         validationResult.propertiesValueMatches++;
847                                     }
848                                 }
849                                 else {
850                                     var propertyValidationResult = new ValidationResult();
851                                     validate(child, propertySchema, propertyValidationResult, matchingSchemas);
852                                     validationResult.mergePropertyMatch(propertyValidationResult);
853                                 }
854                             }
855                         }
856                     }
857                 }
858             }
859             if (typeof schema.additionalProperties === 'object') {
860                 for (var _k = 0, unprocessedProperties_1 = unprocessedProperties; _k < unprocessedProperties_1.length; _k++) {
861                     var propertyName = unprocessedProperties_1[_k];
862                     var child = seenKeys[propertyName];
863                     if (child) {
864                         var propertyValidationResult = new ValidationResult();
865                         validate(child, schema.additionalProperties, propertyValidationResult, matchingSchemas);
866                         validationResult.mergePropertyMatch(propertyValidationResult);
867                     }
868                 }
869             }
870             else if (schema.additionalProperties === false) {
871                 if (unprocessedProperties.length > 0) {
872                     for (var _l = 0, unprocessedProperties_2 = unprocessedProperties; _l < unprocessedProperties_2.length; _l++) {
873                         var propertyName = unprocessedProperties_2[_l];
874                         var child = seenKeys[propertyName];
875                         if (child) {
876                             var propertyNode = child.parent;
877                             validationResult.problems.push({
878                                 location: { offset: propertyNode.keyNode.offset, length: propertyNode.keyNode.length },
879                                 message: schema.errorMessage || localize('DisallowedExtraPropWarning', 'Property {0} is not allowed.', propertyName)
880                             });
881                         }
882                     }
883                 }
884             }
885             if (objects_1.isNumber(schema.maxProperties)) {
886                 if (node.properties.length > schema.maxProperties) {
887                     validationResult.problems.push({
888                         location: { offset: node.offset, length: node.length },
889                         message: localize('MaxPropWarning', 'Object has more properties than limit of {0}.', schema.maxProperties)
890                     });
891                 }
892             }
893             if (objects_1.isNumber(schema.minProperties)) {
894                 if (node.properties.length < schema.minProperties) {
895                     validationResult.problems.push({
896                         location: { offset: node.offset, length: node.length },
897                         message: localize('MinPropWarning', 'Object has fewer properties than the required number of {0}', schema.minProperties)
898                     });
899                 }
900             }
901             if (schema.dependencies) {
902                 for (var _m = 0, _o = Object.keys(schema.dependencies); _m < _o.length; _m++) {
903                     var key = _o[_m];
904                     var prop = seenKeys[key];
905                     if (prop) {
906                         var propertyDep = schema.dependencies[key];
907                         if (Array.isArray(propertyDep)) {
908                             for (var _p = 0, propertyDep_1 = propertyDep; _p < propertyDep_1.length; _p++) {
909                                 var requiredProp = propertyDep_1[_p];
910                                 if (!seenKeys[requiredProp]) {
911                                     validationResult.problems.push({
912                                         location: { offset: node.offset, length: node.length },
913                                         message: localize('RequiredDependentPropWarning', 'Object is missing property {0} required by property {1}.', requiredProp, key)
914                                     });
915                                 }
916                                 else {
917                                     validationResult.propertiesValueMatches++;
918                                 }
919                             }
920                         }
921                         else {
922                             var propertySchema = asSchema(propertyDep);
923                             if (propertySchema) {
924                                 var propertyValidationResult = new ValidationResult();
925                                 validate(node, propertySchema, propertyValidationResult, matchingSchemas);
926                                 validationResult.mergePropertyMatch(propertyValidationResult);
927                             }
928                         }
929                     }
930                 }
931             }
932             var propertyNames = asSchema(schema.propertyNames);
933             if (propertyNames) {
934                 for (var _q = 0, _r = node.properties; _q < _r.length; _q++) {
935                     var f = _r[_q];
936                     var key = f.keyNode;
937                     if (key) {
938                         validate(key, propertyNames, validationResult, NoOpSchemaCollector.instance);
939                     }
940                 }
941             }
942         }
943     }
944     function parse(textDocument, config) {
945         var problems = [];
946         var lastProblemOffset = -1;
947         var text = textDocument.getText();
948         var scanner = Json.createScanner(text, false);
949         var commentRanges = config && config.collectComments ? [] : undefined;
950         function _scanNext() {
951             while (true) {
952                 var token_1 = scanner.scan();
953                 _checkScanError();
954                 switch (token_1) {
955                     case 12 /* LineCommentTrivia */:
956                     case 13 /* BlockCommentTrivia */:
957                         if (Array.isArray(commentRanges)) {
958                             commentRanges.push(jsonLanguageTypes_1.Range.create(textDocument.positionAt(scanner.getTokenOffset()), textDocument.positionAt(scanner.getTokenOffset() + scanner.getTokenLength())));
959                         }
960                         break;
961                     case 15 /* Trivia */:
962                     case 14 /* LineBreakTrivia */:
963                         break;
964                     default:
965                         return token_1;
966                 }
967             }
968         }
969         function _accept(token) {
970             if (scanner.getToken() === token) {
971                 _scanNext();
972                 return true;
973             }
974             return false;
975         }
976         function _errorAtRange(message, code, startOffset, endOffset, severity) {
977             if (severity === void 0) { severity = jsonLanguageTypes_1.DiagnosticSeverity.Error; }
978             if (problems.length === 0 || startOffset !== lastProblemOffset) {
979                 var range = jsonLanguageTypes_1.Range.create(textDocument.positionAt(startOffset), textDocument.positionAt(endOffset));
980                 problems.push(jsonLanguageTypes_1.Diagnostic.create(range, message, severity, code, textDocument.languageId));
981                 lastProblemOffset = startOffset;
982             }
983         }
984         function _error(message, code, node, skipUntilAfter, skipUntil) {
985             if (node === void 0) { node = undefined; }
986             if (skipUntilAfter === void 0) { skipUntilAfter = []; }
987             if (skipUntil === void 0) { skipUntil = []; }
988             var start = scanner.getTokenOffset();
989             var end = scanner.getTokenOffset() + scanner.getTokenLength();
990             if (start === end && start > 0) {
991                 start--;
992                 while (start > 0 && /\s/.test(text.charAt(start))) {
993                     start--;
994                 }
995                 end = start + 1;
996             }
997             _errorAtRange(message, code, start, end);
998             if (node) {
999                 _finalize(node, false);
1000             }
1001             if (skipUntilAfter.length + skipUntil.length > 0) {
1002                 var token_2 = scanner.getToken();
1003                 while (token_2 !== 17 /* EOF */) {
1004                     if (skipUntilAfter.indexOf(token_2) !== -1) {
1005                         _scanNext();
1006                         break;
1007                     }
1008                     else if (skipUntil.indexOf(token_2) !== -1) {
1009                         break;
1010                     }
1011                     token_2 = _scanNext();
1012                 }
1013             }
1014             return node;
1015         }
1016         function _checkScanError() {
1017             switch (scanner.getTokenError()) {
1018                 case 4 /* InvalidUnicode */:
1019                     _error(localize('InvalidUnicode', 'Invalid unicode sequence in string.'), jsonLanguageTypes_1.ErrorCode.InvalidUnicode);
1020                     return true;
1021                 case 5 /* InvalidEscapeCharacter */:
1022                     _error(localize('InvalidEscapeCharacter', 'Invalid escape character in string.'), jsonLanguageTypes_1.ErrorCode.InvalidEscapeCharacter);
1023                     return true;
1024                 case 3 /* UnexpectedEndOfNumber */:
1025                     _error(localize('UnexpectedEndOfNumber', 'Unexpected end of number.'), jsonLanguageTypes_1.ErrorCode.UnexpectedEndOfNumber);
1026                     return true;
1027                 case 1 /* UnexpectedEndOfComment */:
1028                     _error(localize('UnexpectedEndOfComment', 'Unexpected end of comment.'), jsonLanguageTypes_1.ErrorCode.UnexpectedEndOfComment);
1029                     return true;
1030                 case 2 /* UnexpectedEndOfString */:
1031                     _error(localize('UnexpectedEndOfString', 'Unexpected end of string.'), jsonLanguageTypes_1.ErrorCode.UnexpectedEndOfString);
1032                     return true;
1033                 case 6 /* InvalidCharacter */:
1034                     _error(localize('InvalidCharacter', 'Invalid characters in string. Control characters must be escaped.'), jsonLanguageTypes_1.ErrorCode.InvalidCharacter);
1035                     return true;
1036             }
1037             return false;
1038         }
1039         function _finalize(node, scanNext) {
1040             node.length = scanner.getTokenOffset() + scanner.getTokenLength() - node.offset;
1041             if (scanNext) {
1042                 _scanNext();
1043             }
1044             return node;
1045         }
1046         function _parseArray(parent) {
1047             if (scanner.getToken() !== 3 /* OpenBracketToken */) {
1048                 return undefined;
1049             }
1050             var node = new ArrayASTNodeImpl(parent, scanner.getTokenOffset());
1051             _scanNext(); // consume OpenBracketToken
1052             var count = 0;
1053             var needsComma = false;
1054             while (scanner.getToken() !== 4 /* CloseBracketToken */ && scanner.getToken() !== 17 /* EOF */) {
1055                 if (scanner.getToken() === 5 /* CommaToken */) {
1056                     if (!needsComma) {
1057                         _error(localize('ValueExpected', 'Value expected'), jsonLanguageTypes_1.ErrorCode.ValueExpected);
1058                     }
1059                     var commaOffset = scanner.getTokenOffset();
1060                     _scanNext(); // consume comma
1061                     if (scanner.getToken() === 4 /* CloseBracketToken */) {
1062                         if (needsComma) {
1063                             _errorAtRange(localize('TrailingComma', 'Trailing comma'), jsonLanguageTypes_1.ErrorCode.TrailingComma, commaOffset, commaOffset + 1);
1064                         }
1065                         continue;
1066                     }
1067                 }
1068                 else if (needsComma) {
1069                     _error(localize('ExpectedComma', 'Expected comma'), jsonLanguageTypes_1.ErrorCode.CommaExpected);
1070                 }
1071                 var item = _parseValue(node);
1072                 if (!item) {
1073                     _error(localize('PropertyExpected', 'Value expected'), jsonLanguageTypes_1.ErrorCode.ValueExpected, undefined, [], [4 /* CloseBracketToken */, 5 /* CommaToken */]);
1074                 }
1075                 else {
1076                     node.items.push(item);
1077                 }
1078                 needsComma = true;
1079             }
1080             if (scanner.getToken() !== 4 /* CloseBracketToken */) {
1081                 return _error(localize('ExpectedCloseBracket', 'Expected comma or closing bracket'), jsonLanguageTypes_1.ErrorCode.CommaOrCloseBacketExpected, node);
1082             }
1083             return _finalize(node, true);
1084         }
1085         var keyPlaceholder = new StringASTNodeImpl(undefined, 0, 0);
1086         function _parseProperty(parent, keysSeen) {
1087             var node = new PropertyASTNodeImpl(parent, scanner.getTokenOffset(), keyPlaceholder);
1088             var key = _parseString(node);
1089             if (!key) {
1090                 if (scanner.getToken() === 16 /* Unknown */) {
1091                     // give a more helpful error message
1092                     _error(localize('DoubleQuotesExpected', 'Property keys must be doublequoted'), jsonLanguageTypes_1.ErrorCode.Undefined);
1093                     var keyNode = new StringASTNodeImpl(node, scanner.getTokenOffset(), scanner.getTokenLength());
1094                     keyNode.value = scanner.getTokenValue();
1095                     key = keyNode;
1096                     _scanNext(); // consume Unknown
1097                 }
1098                 else {
1099                     return undefined;
1100                 }
1101             }
1102             node.keyNode = key;
1103             var seen = keysSeen[key.value];
1104             if (seen) {
1105                 _errorAtRange(localize('DuplicateKeyWarning', "Duplicate object key"), jsonLanguageTypes_1.ErrorCode.DuplicateKey, node.keyNode.offset, node.keyNode.offset + node.keyNode.length, jsonLanguageTypes_1.DiagnosticSeverity.Warning);
1106                 if (typeof seen === 'object') {
1107                     _errorAtRange(localize('DuplicateKeyWarning', "Duplicate object key"), jsonLanguageTypes_1.ErrorCode.DuplicateKey, seen.keyNode.offset, seen.keyNode.offset + seen.keyNode.length, jsonLanguageTypes_1.DiagnosticSeverity.Warning);
1108                 }
1109                 keysSeen[key.value] = true; // if the same key is duplicate again, avoid duplicate error reporting
1110             }
1111             else {
1112                 keysSeen[key.value] = node;
1113             }
1114             if (scanner.getToken() === 6 /* ColonToken */) {
1115                 node.colonOffset = scanner.getTokenOffset();
1116                 _scanNext(); // consume ColonToken
1117             }
1118             else {
1119                 _error(localize('ColonExpected', 'Colon expected'), jsonLanguageTypes_1.ErrorCode.ColonExpected);
1120                 if (scanner.getToken() === 10 /* StringLiteral */ && textDocument.positionAt(key.offset + key.length).line < textDocument.positionAt(scanner.getTokenOffset()).line) {
1121                     node.length = key.length;
1122                     return node;
1123                 }
1124             }
1125             var value = _parseValue(node);
1126             if (!value) {
1127                 return _error(localize('ValueExpected', 'Value expected'), jsonLanguageTypes_1.ErrorCode.ValueExpected, node, [], [2 /* CloseBraceToken */, 5 /* CommaToken */]);
1128             }
1129             node.valueNode = value;
1130             node.length = value.offset + value.length - node.offset;
1131             return node;
1132         }
1133         function _parseObject(parent) {
1134             if (scanner.getToken() !== 1 /* OpenBraceToken */) {
1135                 return undefined;
1136             }
1137             var node = new ObjectASTNodeImpl(parent, scanner.getTokenOffset());
1138             var keysSeen = Object.create(null);
1139             _scanNext(); // consume OpenBraceToken
1140             var needsComma = false;
1141             while (scanner.getToken() !== 2 /* CloseBraceToken */ && scanner.getToken() !== 17 /* EOF */) {
1142                 if (scanner.getToken() === 5 /* CommaToken */) {
1143                     if (!needsComma) {
1144                         _error(localize('PropertyExpected', 'Property expected'), jsonLanguageTypes_1.ErrorCode.PropertyExpected);
1145                     }
1146                     var commaOffset = scanner.getTokenOffset();
1147                     _scanNext(); // consume comma
1148                     if (scanner.getToken() === 2 /* CloseBraceToken */) {
1149                         if (needsComma) {
1150                             _errorAtRange(localize('TrailingComma', 'Trailing comma'), jsonLanguageTypes_1.ErrorCode.TrailingComma, commaOffset, commaOffset + 1);
1151                         }
1152                         continue;
1153                     }
1154                 }
1155                 else if (needsComma) {
1156                     _error(localize('ExpectedComma', 'Expected comma'), jsonLanguageTypes_1.ErrorCode.CommaExpected);
1157                 }
1158                 var property = _parseProperty(node, keysSeen);
1159                 if (!property) {
1160                     _error(localize('PropertyExpected', 'Property expected'), jsonLanguageTypes_1.ErrorCode.PropertyExpected, undefined, [], [2 /* CloseBraceToken */, 5 /* CommaToken */]);
1161                 }
1162                 else {
1163                     node.properties.push(property);
1164                 }
1165                 needsComma = true;
1166             }
1167             if (scanner.getToken() !== 2 /* CloseBraceToken */) {
1168                 return _error(localize('ExpectedCloseBrace', 'Expected comma or closing brace'), jsonLanguageTypes_1.ErrorCode.CommaOrCloseBraceExpected, node);
1169             }
1170             return _finalize(node, true);
1171         }
1172         function _parseString(parent) {
1173             if (scanner.getToken() !== 10 /* StringLiteral */) {
1174                 return undefined;
1175             }
1176             var node = new StringASTNodeImpl(parent, scanner.getTokenOffset());
1177             node.value = scanner.getTokenValue();
1178             return _finalize(node, true);
1179         }
1180         function _parseNumber(parent) {
1181             if (scanner.getToken() !== 11 /* NumericLiteral */) {
1182                 return undefined;
1183             }
1184             var node = new NumberASTNodeImpl(parent, scanner.getTokenOffset());
1185             if (scanner.getTokenError() === 0 /* None */) {
1186                 var tokenValue = scanner.getTokenValue();
1187                 try {
1188                     var numberValue = JSON.parse(tokenValue);
1189                     if (!objects_1.isNumber(numberValue)) {
1190                         return _error(localize('InvalidNumberFormat', 'Invalid number format.'), jsonLanguageTypes_1.ErrorCode.Undefined, node);
1191                     }
1192                     node.value = numberValue;
1193                 }
1194                 catch (e) {
1195                     return _error(localize('InvalidNumberFormat', 'Invalid number format.'), jsonLanguageTypes_1.ErrorCode.Undefined, node);
1196                 }
1197                 node.isInteger = tokenValue.indexOf('.') === -1;
1198             }
1199             return _finalize(node, true);
1200         }
1201         function _parseLiteral(parent) {
1202             var node;
1203             switch (scanner.getToken()) {
1204                 case 7 /* NullKeyword */:
1205                     return _finalize(new NullASTNodeImpl(parent, scanner.getTokenOffset()), true);
1206                 case 8 /* TrueKeyword */:
1207                     return _finalize(new BooleanASTNodeImpl(parent, true, scanner.getTokenOffset()), true);
1208                 case 9 /* FalseKeyword */:
1209                     return _finalize(new BooleanASTNodeImpl(parent, false, scanner.getTokenOffset()), true);
1210                 default:
1211                     return undefined;
1212             }
1213         }
1214         function _parseValue(parent) {
1215             return _parseArray(parent) || _parseObject(parent) || _parseString(parent) || _parseNumber(parent) || _parseLiteral(parent);
1216         }
1217         var _root = undefined;
1218         var token = _scanNext();
1219         if (token !== 17 /* EOF */) {
1220             _root = _parseValue(_root);
1221             if (!_root) {
1222                 _error(localize('Invalid symbol', 'Expected a JSON object, array or literal.'), jsonLanguageTypes_1.ErrorCode.Undefined);
1223             }
1224             else if (scanner.getToken() !== 17 /* EOF */) {
1225                 _error(localize('End of file expected', 'End of file expected.'), jsonLanguageTypes_1.ErrorCode.Undefined);
1226             }
1227         }
1228         return new JSONDocument(_root, problems, commentRanges);
1229     }
1230     exports.parse = parse;
1231 });