123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321 |
- "use strict";
- Object.defineProperty(exports, "__esModule", { value: true });
- exports.AvroSchemaEncoder = void 0;
- const AvroEncoder_1 = require("./AvroEncoder");
- const AvroSchemaValidator_1 = require("./AvroSchemaValidator");
- class AvroSchemaEncoder {
- constructor(writer) {
- this.writer = writer;
- this.namedSchemas = new Map();
- this.encoder = new AvroEncoder_1.AvroEncoder(writer);
- this.validator = new AvroSchemaValidator_1.AvroSchemaValidator();
- }
- encode(value, schema, selectedIndex) {
- this.writer.reset();
- this.namedSchemas.clear();
- if (!this.validator.validateSchema(schema)) {
- throw new Error('Invalid Avro schema');
- }
- if (!this.validator.validateValue(value, schema)) {
- throw new Error('Value does not conform to schema');
- }
- this.collectNamedSchemas(schema);
- if (Array.isArray(schema) && selectedIndex !== undefined) {
- this.writeUnion(value, schema, selectedIndex);
- }
- else {
- this.writeValue(value, schema);
- }
- return this.writer.flush();
- }
- writeNull(schema) {
- this.validateSchemaType(schema, 'null');
- this.encoder.writeNull();
- }
- writeBoolean(value, schema) {
- this.validateSchemaType(schema, 'boolean');
- this.encoder.writeBoolean(value);
- }
- writeInt(value, schema) {
- this.validateSchemaType(schema, 'int');
- if (!Number.isInteger(value) || value < -2147483648 || value > 2147483647) {
- throw new Error('Value is not a valid 32-bit integer');
- }
- this.encoder.writeInt(value);
- }
- writeLong(value, schema) {
- this.validateSchemaType(schema, 'long');
- this.encoder.writeLong(value);
- }
- writeFloat(value, schema) {
- this.validateSchemaType(schema, 'float');
- this.encoder.writeFloat(value);
- }
- writeDouble(value, schema) {
- this.validateSchemaType(schema, 'double');
- this.encoder.writeDouble(value);
- }
- writeBytes(value, schema) {
- this.validateSchemaType(schema, 'bytes');
- this.encoder.writeBin(value);
- }
- writeString(value, schema) {
- this.validateSchemaType(schema, 'string');
- this.encoder.writeStr(value);
- }
- writeRecord(value, schema) {
- if (typeof schema === 'object' && schema.type !== 'record') {
- throw new Error('Schema is not a record schema');
- }
- const recordSchema = this.resolveSchema(schema);
- if (recordSchema.type !== 'record') {
- throw new Error('Schema is not a record schema');
- }
- for (let i = 0; i < recordSchema.fields.length; i++) {
- const field = recordSchema.fields[i];
- const fieldValue = value[field.name];
- if (fieldValue !== undefined) {
- this.writeValue(fieldValue, field.type);
- }
- else if (field.default !== undefined) {
- this.writeValue(field.default, field.type);
- }
- else {
- throw new Error(`Missing required field: ${field.name}`);
- }
- }
- }
- writeEnum(value, schema) {
- if (typeof schema === 'object' && schema.type !== 'enum') {
- throw new Error('Schema is not an enum schema');
- }
- const enumSchema = this.resolveSchema(schema);
- if (enumSchema.type !== 'enum') {
- throw new Error('Schema is not an enum schema');
- }
- const index = enumSchema.symbols.indexOf(value);
- if (index === -1) {
- throw new Error(`Invalid enum value: ${value}`);
- }
- this.writeVarIntSigned(this.encodeZigZag32(index));
- }
- writeArray(value, schema) {
- if (typeof schema === 'object' && schema.type !== 'array') {
- throw new Error('Schema is not an array schema');
- }
- const arraySchema = this.resolveSchema(schema);
- if (arraySchema.type !== 'array') {
- throw new Error('Schema is not an array schema');
- }
- this.writeVarIntUnsigned(value.length);
- const length = value.length;
- for (let i = 0; i < length; i++) {
- this.writeValue(value[i], arraySchema.items);
- }
- this.writeVarIntUnsigned(0);
- }
- writeMap(value, schema) {
- if (typeof schema === 'object' && schema.type !== 'map') {
- throw new Error('Schema is not a map schema');
- }
- const mapSchema = this.resolveSchema(schema);
- if (mapSchema.type !== 'map') {
- throw new Error('Schema is not a map schema');
- }
- const entries = Object.entries(value);
- this.writeVarIntUnsigned(entries.length);
- const length = entries.length;
- for (let i = 0; i < length; i++) {
- const entry = entries[i];
- this.encoder.writeStr(entry[0]);
- this.writeValue(entry[1], mapSchema.values);
- }
- this.writeVarIntUnsigned(0);
- }
- writeUnion(value, schema, selectedIndex) {
- if (!Array.isArray(schema)) {
- throw new Error('Schema is not a union schema');
- }
- let index = selectedIndex;
- if (index === undefined) {
- index = schema.findIndex((subSchema) => this.validator.validateValue(value, subSchema));
- if (index === -1) {
- throw new Error('Value does not match any schema in the union');
- }
- }
- if (index < 0 || index >= schema.length) {
- throw new Error('Invalid union index');
- }
- this.writeVarIntSigned(this.encodeZigZag32(index));
- this.writeValue(value, schema[index]);
- }
- writeFixed(value, schema) {
- if (typeof schema === 'object' && schema.type !== 'fixed') {
- throw new Error('Schema is not a fixed schema');
- }
- const fixedSchema = this.resolveSchema(schema);
- if (fixedSchema.type !== 'fixed') {
- throw new Error('Schema is not a fixed schema');
- }
- if (value.length !== fixedSchema.size) {
- throw new Error(`Fixed value length ${value.length} does not match schema size ${fixedSchema.size}`);
- }
- this.writer.buf(value, value.length);
- }
- writeNumber(value, schema) {
- const resolvedSchema = this.resolveSchema(schema);
- const schemaType = typeof resolvedSchema === 'string'
- ? resolvedSchema
- : Array.isArray(resolvedSchema)
- ? 'union'
- : resolvedSchema.type;
- switch (schemaType) {
- case 'int':
- this.writeInt(value, schema);
- break;
- case 'long':
- this.writeLong(value, schema);
- break;
- case 'float':
- this.writeFloat(value, schema);
- break;
- case 'double':
- this.writeDouble(value, schema);
- break;
- default:
- throw new Error(`Schema type ${schemaType} is not a numeric type`);
- }
- }
- writeValue(value, schema) {
- const resolvedSchema = this.resolveSchema(schema);
- if (typeof resolvedSchema === 'string') {
- switch (resolvedSchema) {
- case 'null':
- this.encoder.writeNull();
- break;
- case 'boolean':
- this.encoder.writeBoolean(value);
- break;
- case 'int':
- this.encoder.writeInt(value);
- break;
- case 'long':
- this.encoder.writeLong(value);
- break;
- case 'float':
- this.encoder.writeFloat(value);
- break;
- case 'double':
- this.encoder.writeDouble(value);
- break;
- case 'bytes':
- this.encoder.writeBin(value);
- break;
- case 'string':
- this.encoder.writeStr(value);
- break;
- default:
- throw new Error(`Unknown primitive type: ${resolvedSchema}`);
- }
- return;
- }
- if (Array.isArray(resolvedSchema)) {
- this.writeUnion(value, resolvedSchema);
- return;
- }
- switch (resolvedSchema.type) {
- case 'record':
- this.writeRecord(value, resolvedSchema);
- break;
- case 'enum':
- this.writeEnum(value, resolvedSchema);
- break;
- case 'array':
- this.writeArray(value, resolvedSchema);
- break;
- case 'map':
- this.writeMap(value, resolvedSchema);
- break;
- case 'fixed':
- this.writeFixed(value, resolvedSchema);
- break;
- default:
- throw new Error(`Unknown schema type: ${resolvedSchema.type}`);
- }
- }
- validateSchemaType(schema, expectedType) {
- const resolvedSchema = this.resolveSchema(schema);
- const actualType = typeof resolvedSchema === 'string'
- ? resolvedSchema
- : Array.isArray(resolvedSchema)
- ? 'union'
- : resolvedSchema.type;
- if (actualType !== expectedType) {
- throw new Error(`Expected schema type ${expectedType}, got ${actualType}`);
- }
- }
- resolveSchema(schema) {
- if (typeof schema === 'string') {
- const namedSchema = this.namedSchemas.get(schema);
- return namedSchema || schema;
- }
- return schema;
- }
- collectNamedSchemas(schema) {
- if (typeof schema === 'string' || Array.isArray(schema)) {
- return;
- }
- if (typeof schema === 'object' && schema !== null) {
- switch (schema.type) {
- case 'record':
- const recordSchema = schema;
- const recordFullName = this.getFullName(recordSchema.name, recordSchema.namespace);
- this.namedSchemas.set(recordFullName, recordSchema);
- recordSchema.fields.forEach((field) => this.collectNamedSchemas(field.type));
- break;
- case 'enum':
- const enumSchema = schema;
- const enumFullName = this.getFullName(enumSchema.name, enumSchema.namespace);
- this.namedSchemas.set(enumFullName, enumSchema);
- break;
- case 'fixed':
- const fixedSchema = schema;
- const fixedFullName = this.getFullName(fixedSchema.name, fixedSchema.namespace);
- this.namedSchemas.set(fixedFullName, fixedSchema);
- break;
- case 'array':
- this.collectNamedSchemas(schema.items);
- break;
- case 'map':
- this.collectNamedSchemas(schema.values);
- break;
- }
- }
- }
- getFullName(name, namespace) {
- return namespace ? `${namespace}.${name}` : name;
- }
- writeVarIntUnsigned(value) {
- const writer = this.writer;
- let n = value >>> 0;
- while (n >= 0x80) {
- writer.u8((n & 0x7f) | 0x80);
- n >>>= 7;
- }
- writer.u8(n & 0x7f);
- }
- writeVarIntSigned(value) {
- const writer = this.writer;
- let n = value >>> 0;
- while (n >= 0x80) {
- writer.u8((n & 0x7f) | 0x80);
- n >>>= 7;
- }
- writer.u8(n & 0x7f);
- }
- encodeZigZag32(value) {
- return (value << 1) ^ (value >> 31);
- }
- }
- exports.AvroSchemaEncoder = AvroSchemaEncoder;
- //# sourceMappingURL=AvroSchemaEncoder.js.map
|