UNPKG

@jsonjoy.com/json-type

Version:

High-performance JSON Pointer implementation

121 lines 6.76 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.MsgPackCodegen = void 0; const tslib_1 = require("tslib"); const JsExpression_1 = require("@jsonjoy.com/codegen/lib/util/JsExpression"); const normalizeAccessor_1 = require("@jsonjoy.com/codegen/lib/util/normalizeAccessor"); const MsgPackEncoder_1 = require("@jsonjoy.com/json-pack/lib/msgpack/MsgPackEncoder"); const type_1 = require("../../../type"); const util_1 = require("../../util"); const AbstractBinaryCodegen_1 = require("../AbstractBinaryCodegen"); const writer_1 = require("../writer"); const once_1 = require("thingies/lib/once"); let MsgPackCodegen = (() => { var _a; let _classSuper = AbstractBinaryCodegen_1.AbstractBinaryCodegen; let _instanceExtraInitializers = []; let _linkGet_decorators; return _a = class MsgPackCodegen extends _classSuper { constructor() { super(...arguments); this.encoder = (tslib_1.__runInitializers(this, _instanceExtraInitializers), new MsgPackEncoder_1.MsgPackEncoder(writer_1.writer)); } linkGet() { this.codegen.linkDependency(_a.get, 'get'); } onObj(path, value, type) { const codegen = this.codegen; const r = codegen.r(); const fields = type.keys; const length = fields.length; const requiredFields = fields.filter((field) => !(field instanceof type_1.KeyOptType)); const optionalFields = fields.filter((field) => field instanceof type_1.KeyOptType); const requiredLength = requiredFields.length; const optionalLength = optionalFields.length; const totalMaxKnownFields = requiredLength + optionalLength; if (totalMaxKnownFields > 0xffff) throw new Error('Too many fields'); const encodeUnknownFields = !!type.schema.encodeUnknownKeys; const rFieldCount = codegen.r(); const emitRequiredFields = () => { for (let i = 0; i < requiredLength; i++) { const field = requiredFields[i]; this.blob(this.gen((encoder) => encoder.writeStr(field.key))); const accessor = (0, normalizeAccessor_1.normalizeAccessor)(field.key); this.onNode([...path, field.key], new JsExpression_1.JsExpression(() => `${r}${accessor}`), field.val); } }; const emitOptionalFields = () => { for (let i = 0; i < optionalLength; i++) { const field = optionalFields[i]; const accessor = (0, normalizeAccessor_1.normalizeAccessor)(field.key); codegen.if(`${r}${accessor} !== undefined`, () => { codegen.js(`${rFieldCount}++;`); this.blob(this.gen((encoder) => encoder.writeStr(field.key))); this.onNode([...path, field.key], new JsExpression_1.JsExpression(() => `${r}${accessor}`), field.val); }); } }; const emitUnknownFields = () => { const ri = codegen.r(); const rKeys = codegen.r(); const rKey = codegen.r(); const rLength = codegen.r(); const keys = fields.map((field) => JSON.stringify(field.key)); const rKnownFields = codegen.addConstant(`new Set([${keys.join(',')}])`); codegen.js(`var ${rKeys} = Object.keys(${r}), ${rLength} = ${rKeys}.length, ${rKey};`); codegen.js(`for (var ${ri} = 0; ${ri} < ${rLength}; ${ri}++) {`); codegen.js(`${rKey} = ${rKeys}[${ri}];`); codegen.js(`if (${rKnownFields}.has(${rKey})) continue;`); codegen.js(`${rFieldCount}++;`); codegen.js(`encoder.writeStr(${rKey});`); codegen.js(`encoder.writeAny(${r}[${rKey}]);`); codegen.js(`}`); }; codegen.js(/* js */ `var ${r} = ${value.use()};`); if (!encodeUnknownFields && !optionalLength) { this.blob(this.gen((encoder) => encoder.writeObjHdr(length))); emitRequiredFields(); } else if (!encodeUnknownFields) { codegen.js(`var ${rFieldCount} = ${requiredLength};`); const rHeaderPosition = codegen.var('writer.x'); this.blob(this.gen((encoder) => encoder.writeObjHdr(0xffff))); emitRequiredFields(); emitOptionalFields(); codegen.js(`view.setUint16(${rHeaderPosition} + 1, ${rFieldCount});`); } else { codegen.js(`var ${rFieldCount} = ${requiredLength};`); const rHeaderPosition = codegen.var('writer.x'); this.blob(this.gen((encoder) => encoder.writeObjHdr(0xffffffff))); emitRequiredFields(); emitOptionalFields(); emitUnknownFields(); codegen.js(`view.setUint32(${rHeaderPosition} + 1, ${rFieldCount});`); } } onKey(path, r, type) { this.onNode([...path, type.key], r, type.val); } genEncoder(type) { return _a.get(type); } }, (() => { const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0; _linkGet_decorators = [once_1.once]; tslib_1.__esDecorate(_a, null, _linkGet_decorators, { kind: "method", name: "linkGet", static: false, private: false, access: { has: obj => "linkGet" in obj, get: obj => obj.linkGet }, metadata: _metadata }, null, _instanceExtraInitializers); if (_metadata) Object.defineProperty(_a, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata }); })(), _a.get = (0, util_1.lazyKeyedFactory)((type, name) => { const codegen = new _a(type, name); const r = codegen.codegen.options.args[0]; const expression = new JsExpression_1.JsExpression(() => r); codegen.onNode([], expression, type); return codegen.compile(); }), _a; })(); exports.MsgPackCodegen = MsgPackCodegen; //# sourceMappingURL=MsgPackCodegen.js.map