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