massive update, probably broken
[dotfiles/.git] / .config / coc / extensions / node_modules / coc-prettier / node_modules / table / node_modules / ajv / dist / compile / jtd / parse.js
1 "use strict";
2 Object.defineProperty(exports, "__esModule", { value: true });
3 const types_1 = require("./types");
4 const __1 = require("..");
5 const codegen_1 = require("../codegen");
6 const ref_error_1 = require("../ref_error");
7 const names_1 = require("../names");
8 const code_1 = require("../../vocabularies/code");
9 const ref_1 = require("../../vocabularies/jtd/ref");
10 const type_1 = require("../../vocabularies/jtd/type");
11 const parseJson_1 = require("../../runtime/parseJson");
12 const util_1 = require("../util");
13 const timestamp_1 = require("../../runtime/timestamp");
14 const genParse = {
15     elements: parseElements,
16     values: parseValues,
17     discriminator: parseDiscriminator,
18     properties: parseProperties,
19     optionalProperties: parseProperties,
20     enum: parseEnum,
21     type: parseType,
22     ref: parseRef,
23 };
24 function compileParser(sch, definitions) {
25     const _sch = __1.getCompilingSchema.call(this, sch);
26     if (_sch)
27         return _sch;
28     const { es5, lines } = this.opts.code;
29     const { ownProperties } = this.opts;
30     const gen = new codegen_1.CodeGen(this.scope, { es5, lines, ownProperties });
31     const parseName = gen.scopeName("parse");
32     const cxt = {
33         self: this,
34         gen,
35         schema: sch.schema,
36         schemaEnv: sch,
37         definitions,
38         data: names_1.default.data,
39         parseName,
40         char: gen.name("c"),
41     };
42     let sourceCode;
43     try {
44         this._compilations.add(sch);
45         sch.parseName = parseName;
46         parserFunction(cxt);
47         gen.optimize(this.opts.code.optimize);
48         const parseFuncCode = gen.toString();
49         sourceCode = `${gen.scopeRefs(names_1.default.scope)}return ${parseFuncCode}`;
50         const makeParse = new Function(`${names_1.default.scope}`, sourceCode);
51         const parse = makeParse(this.scope.get());
52         this.scope.value(parseName, { ref: parse });
53         sch.parse = parse;
54     }
55     catch (e) {
56         if (sourceCode)
57             this.logger.error("Error compiling parser, function code:", sourceCode);
58         delete sch.parse;
59         delete sch.parseName;
60         throw e;
61     }
62     finally {
63         this._compilations.delete(sch);
64     }
65     return sch;
66 }
67 exports.default = compileParser;
68 const undef = (0, codegen_1._) `undefined`;
69 function parserFunction(cxt) {
70     const { gen, parseName, char } = cxt;
71     gen.func(parseName, (0, codegen_1._) `${names_1.default.json}, ${names_1.default.jsonPos}, ${names_1.default.jsonPart}`, false, () => {
72         gen.let(names_1.default.data);
73         gen.let(char);
74         gen.assign((0, codegen_1._) `${parseName}.message`, undef);
75         gen.assign((0, codegen_1._) `${parseName}.position`, undef);
76         gen.assign(names_1.default.jsonPos, (0, codegen_1._) `${names_1.default.jsonPos} || 0`);
77         gen.const(names_1.default.jsonLen, (0, codegen_1._) `${names_1.default.json}.length`);
78         parseCode(cxt);
79         skipWhitespace(cxt);
80         gen.if(names_1.default.jsonPart, () => {
81             gen.assign((0, codegen_1._) `${parseName}.position`, names_1.default.jsonPos);
82             gen.return(names_1.default.data);
83         });
84         gen.if((0, codegen_1._) `${names_1.default.jsonPos} === ${names_1.default.jsonLen}`, () => gen.return(names_1.default.data));
85         jsonSyntaxError(cxt);
86     });
87 }
88 function parseCode(cxt) {
89     let form;
90     for (const key of types_1.jtdForms) {
91         if (key in cxt.schema) {
92             form = key;
93             break;
94         }
95     }
96     if (form)
97         parseNullable(cxt, genParse[form]);
98     else
99         parseEmpty(cxt);
100 }
101 const parseBoolean = parseBooleanToken(true, parseBooleanToken(false, jsonSyntaxError));
102 function parseNullable(cxt, parseForm) {
103     const { gen, schema, data } = cxt;
104     if (!schema.nullable)
105         return parseForm(cxt);
106     tryParseToken(cxt, "null", parseForm, () => gen.assign(data, null));
107 }
108 function parseElements(cxt) {
109     const { gen, schema, data } = cxt;
110     parseToken(cxt, "[");
111     const ix = gen.let("i", 0);
112     gen.assign(data, (0, codegen_1._) `[]`);
113     parseItems(cxt, "]", () => {
114         const el = gen.let("el");
115         parseCode({ ...cxt, schema: schema.elements, data: el });
116         gen.assign((0, codegen_1._) `${data}[${ix}++]`, el);
117     });
118 }
119 function parseValues(cxt) {
120     const { gen, schema, data } = cxt;
121     parseToken(cxt, "{");
122     gen.assign(data, (0, codegen_1._) `{}`);
123     parseItems(cxt, "}", () => parseKeyValue(cxt, schema.values));
124 }
125 function parseItems(cxt, endToken, block) {
126     tryParseItems(cxt, endToken, block);
127     parseToken(cxt, endToken);
128 }
129 function tryParseItems(cxt, endToken, block) {
130     const { gen } = cxt;
131     gen.for((0, codegen_1._) `;${names_1.default.jsonPos}<${names_1.default.jsonLen} && ${jsonSlice(1)}!==${endToken};`, () => {
132         block();
133         tryParseToken(cxt, ",", () => gen.break(), hasItem);
134     });
135     function hasItem() {
136         tryParseToken(cxt, endToken, () => { }, jsonSyntaxError);
137     }
138 }
139 function parseKeyValue(cxt, schema) {
140     const { gen } = cxt;
141     const key = gen.let("key");
142     parseString({ ...cxt, data: key });
143     parseToken(cxt, ":");
144     parsePropertyValue(cxt, key, schema);
145 }
146 function parseDiscriminator(cxt) {
147     const { gen, data, schema } = cxt;
148     const { discriminator, mapping } = schema;
149     parseToken(cxt, "{");
150     gen.assign(data, (0, codegen_1._) `{}`);
151     const startPos = gen.const("pos", names_1.default.jsonPos);
152     const value = gen.let("value");
153     const tag = gen.let("tag");
154     tryParseItems(cxt, "}", () => {
155         const key = gen.let("key");
156         parseString({ ...cxt, data: key });
157         parseToken(cxt, ":");
158         gen.if((0, codegen_1._) `${key} === ${discriminator}`, () => {
159             parseString({ ...cxt, data: tag });
160             gen.assign((0, codegen_1._) `${data}[${key}]`, tag);
161             gen.break();
162         }, () => parseEmpty({ ...cxt, data: value }) // can be discarded/skipped
163         );
164     });
165     gen.assign(names_1.default.jsonPos, startPos);
166     gen.if((0, codegen_1._) `${tag} === undefined`);
167     parsingError(cxt, (0, codegen_1.str) `discriminator tag not found`);
168     for (const tagValue in mapping) {
169         gen.elseIf((0, codegen_1._) `${tag} === ${tagValue}`);
170         parseSchemaProperties({ ...cxt, schema: mapping[tagValue] }, discriminator);
171     }
172     gen.else();
173     parsingError(cxt, (0, codegen_1.str) `discriminator value not in schema`);
174     gen.endIf();
175 }
176 function parseProperties(cxt) {
177     const { gen, data } = cxt;
178     parseToken(cxt, "{");
179     gen.assign(data, (0, codegen_1._) `{}`);
180     parseSchemaProperties(cxt);
181 }
182 function parseSchemaProperties(cxt, discriminator) {
183     const { gen, schema, data } = cxt;
184     const { properties, optionalProperties, additionalProperties } = schema;
185     parseItems(cxt, "}", () => {
186         const key = gen.let("key");
187         parseString({ ...cxt, data: key });
188         parseToken(cxt, ":");
189         gen.if(false);
190         parseDefinedProperty(cxt, key, properties);
191         parseDefinedProperty(cxt, key, optionalProperties);
192         if (discriminator) {
193             gen.elseIf((0, codegen_1._) `${key} === ${discriminator}`);
194             const tag = gen.let("tag");
195             parseString({ ...cxt, data: tag }); // can be discarded, it is already assigned
196         }
197         gen.else();
198         if (additionalProperties) {
199             parseEmpty({ ...cxt, data: (0, codegen_1._) `${data}[${key}]` });
200         }
201         else {
202             parsingError(cxt, (0, codegen_1.str) `property ${key} not allowed`);
203         }
204         gen.endIf();
205     });
206     if (properties) {
207         const hasProp = (0, code_1.hasPropFunc)(gen);
208         const allProps = (0, codegen_1.and)(...Object.keys(properties).map((p) => (0, codegen_1._) `${hasProp}.call(${data}, ${p})`));
209         gen.if((0, codegen_1.not)(allProps), () => parsingError(cxt, (0, codegen_1.str) `missing required properties`));
210     }
211 }
212 function parseDefinedProperty(cxt, key, schemas = {}) {
213     const { gen } = cxt;
214     for (const prop in schemas) {
215         gen.elseIf((0, codegen_1._) `${key} === ${prop}`);
216         parsePropertyValue(cxt, key, schemas[prop]);
217     }
218 }
219 function parsePropertyValue(cxt, key, schema) {
220     parseCode({ ...cxt, schema, data: (0, codegen_1._) `${cxt.data}[${key}]` });
221 }
222 function parseType(cxt) {
223     const { gen, schema, data, self } = cxt;
224     switch (schema.type) {
225         case "boolean":
226             parseBoolean(cxt);
227             break;
228         case "string":
229             parseString(cxt);
230             break;
231         case "timestamp": {
232             parseString(cxt);
233             const vts = (0, util_1.useFunc)(gen, timestamp_1.default);
234             const { allowDate, parseDate } = self.opts;
235             const notValid = allowDate ? (0, codegen_1._) `!${vts}(${data}, true)` : (0, codegen_1._) `!${vts}(${data})`;
236             const fail = parseDate
237                 ? (0, codegen_1.or)(notValid, (0, codegen_1._) `(${data} = new Date(${data}), false)`, (0, codegen_1._) `isNaN(${data}.valueOf())`)
238                 : notValid;
239             gen.if(fail, () => parsingError(cxt, (0, codegen_1.str) `invalid timestamp`));
240             break;
241         }
242         case "float32":
243         case "float64":
244             parseNumber(cxt);
245             break;
246         default: {
247             const t = schema.type;
248             if (!self.opts.int32range && (t === "int32" || t === "uint32")) {
249                 parseNumber(cxt, 16); // 2 ** 53 - max safe integer
250                 if (t === "uint32") {
251                     gen.if((0, codegen_1._) `${data} < 0`, () => parsingError(cxt, (0, codegen_1.str) `integer out of range`));
252                 }
253             }
254             else {
255                 const [min, max, maxDigits] = type_1.intRange[t];
256                 parseNumber(cxt, maxDigits);
257                 gen.if((0, codegen_1._) `${data} < ${min} || ${data} > ${max}`, () => parsingError(cxt, (0, codegen_1.str) `integer out of range`));
258             }
259         }
260     }
261 }
262 function parseString(cxt) {
263     parseToken(cxt, '"');
264     parseWith(cxt, parseJson_1.parseJsonString);
265 }
266 function parseEnum(cxt) {
267     const { gen, data, schema } = cxt;
268     const enumSch = schema.enum;
269     parseToken(cxt, '"');
270     // TODO loopEnum
271     gen.if(false);
272     for (const value of enumSch) {
273         const valueStr = JSON.stringify(value).slice(1); // remove starting quote
274         gen.elseIf((0, codegen_1._) `${jsonSlice(valueStr.length)} === ${valueStr}`);
275         gen.assign(data, (0, codegen_1.str) `${value}`);
276         gen.add(names_1.default.jsonPos, valueStr.length);
277     }
278     gen.else();
279     jsonSyntaxError(cxt);
280     gen.endIf();
281 }
282 function parseNumber(cxt, maxDigits) {
283     const { gen } = cxt;
284     skipWhitespace(cxt);
285     gen.if((0, codegen_1._) `"-0123456789".indexOf(${jsonSlice(1)}) < 0`, () => jsonSyntaxError(cxt), () => parseWith(cxt, parseJson_1.parseJsonNumber, maxDigits));
286 }
287 function parseBooleanToken(bool, fail) {
288     return (cxt) => {
289         const { gen, data } = cxt;
290         tryParseToken(cxt, `${bool}`, () => fail(cxt), () => gen.assign(data, bool));
291     };
292 }
293 function parseRef(cxt) {
294     const { gen, self, definitions, schema, schemaEnv } = cxt;
295     const { ref } = schema;
296     const refSchema = definitions[ref];
297     if (!refSchema)
298         throw new ref_error_1.default("", ref, `No definition ${ref}`);
299     if (!(0, ref_1.hasRef)(refSchema))
300         return parseCode({ ...cxt, schema: refSchema });
301     const { root } = schemaEnv;
302     const sch = compileParser.call(self, new __1.SchemaEnv({ schema: refSchema, root }), definitions);
303     partialParse(cxt, getParser(gen, sch), true);
304 }
305 function getParser(gen, sch) {
306     return sch.parse
307         ? gen.scopeValue("parse", { ref: sch.parse })
308         : (0, codegen_1._) `${gen.scopeValue("wrapper", { ref: sch })}.parse`;
309 }
310 function parseEmpty(cxt) {
311     parseWith(cxt, parseJson_1.parseJson);
312 }
313 function parseWith(cxt, parseFunc, args) {
314     partialParse(cxt, (0, util_1.useFunc)(cxt.gen, parseFunc), args);
315 }
316 function partialParse(cxt, parseFunc, args) {
317     const { gen, data } = cxt;
318     gen.assign(data, (0, codegen_1._) `${parseFunc}(${names_1.default.json}, ${names_1.default.jsonPos}${args ? (0, codegen_1._) `, ${args}` : codegen_1.nil})`);
319     gen.assign(names_1.default.jsonPos, (0, codegen_1._) `${parseFunc}.position`);
320     gen.if((0, codegen_1._) `${data} === undefined`, () => parsingError(cxt, (0, codegen_1._) `${parseFunc}.message`));
321 }
322 function parseToken(cxt, tok) {
323     tryParseToken(cxt, tok, jsonSyntaxError);
324 }
325 function tryParseToken(cxt, tok, fail, success) {
326     const { gen } = cxt;
327     const n = tok.length;
328     skipWhitespace(cxt);
329     gen.if((0, codegen_1._) `${jsonSlice(n)} === ${tok}`, () => {
330         gen.add(names_1.default.jsonPos, n);
331         success === null || success === void 0 ? void 0 : success(cxt);
332     }, () => fail(cxt));
333 }
334 function skipWhitespace({ gen, char: c }) {
335     gen.code((0, codegen_1._) `while((${c}=${names_1.default.json}[${names_1.default.jsonPos}],${c}===" "||${c}==="\\n"||${c}==="\\r"||${c}==="\\t"))${names_1.default.jsonPos}++;`);
336 }
337 function jsonSlice(len) {
338     return len === 1
339         ? (0, codegen_1._) `${names_1.default.json}[${names_1.default.jsonPos}]`
340         : (0, codegen_1._) `${names_1.default.json}.slice(${names_1.default.jsonPos}, ${names_1.default.jsonPos}+${len})`;
341 }
342 function jsonSyntaxError(cxt) {
343     parsingError(cxt, (0, codegen_1._) `"unexpected token " + ${names_1.default.json}[${names_1.default.jsonPos}]`);
344 }
345 function parsingError({ gen, parseName }, msg) {
346     gen.assign((0, codegen_1._) `${parseName}.message`, msg);
347     gen.assign((0, codegen_1._) `${parseName}.position`, names_1.default.jsonPos);
348     gen.return(undef);
349 }
350 //# sourceMappingURL=parse.js.map