From 4444f36ff91c4425e777defb90269075b343e07f Mon Sep 17 00:00:00 2001 From: achingbrain Date: Thu, 17 Sep 2026 15:53:08 +0300 Subject: [PATCH 1/6] feat!: support packed fields Adds support for packed fields Fixes #24 BREAKING CHANGE: non-string/byte scalar fields are now packed by default - annotate with `[packed=false]` or `[features.repeated_field_encoding=EXPANDED]` for the previous behavior --- packages/protons-benchmark/package.json | 2 +- packages/protons/package.json | 2 +- packages/protons/src/fields/array-field.ts | 82 +- packages/protons/src/fields/field.ts | 3 + packages/protons/src/types/enum.ts | 10 +- packages/protons/src/types/index.ts | 4 +- packages/protons/src/types/message.ts | 30 +- packages/protons/src/types/primitive.ts | 70 +- packages/protons/test/fixtures/basic.ts | 48 +- packages/protons/test/fixtures/bitswap.ts | 164 +- packages/protons/test/fixtures/circuit.ts | 64 +- .../test/fixtures/custom-option-jstype.ts | 236 +- packages/protons/test/fixtures/daemon.ts | 616 +-- packages/protons/test/fixtures/dht.ts | 116 +- packages/protons/test/fixtures/maps.ts | 247 +- packages/protons/test/fixtures/noise.ts | 52 +- packages/protons/test/fixtures/oneof.ts | 80 +- packages/protons/test/fixtures/optional.ts | 116 +- packages/protons/test/fixtures/packed.proto | 86 + packages/protons/test/fixtures/packed.ts | 3710 +++++++++++++++++ packages/protons/test/fixtures/peer.ts | 96 +- packages/protons/test/fixtures/proto2.ts | 24 +- .../protons/test/fixtures/protons-options.ts | 76 +- packages/protons/test/fixtures/repeated.ts | 192 +- packages/protons/test/fixtures/singular.ts | 116 +- packages/protons/test/fixtures/streaming.ts | 280 +- packages/protons/test/fixtures/test.ts | 116 +- packages/protons/test/oneof.spec.ts | 120 +- packages/protons/test/packed.spec.ts | 154 + packages/protons/test/utils/compat.ts | 152 + 30 files changed, 5603 insertions(+), 1461 deletions(-) create mode 100644 packages/protons/test/fixtures/packed.proto create mode 100644 packages/protons/test/fixtures/packed.ts create mode 100644 packages/protons/test/packed.spec.ts create mode 100644 packages/protons/test/utils/compat.ts diff --git a/packages/protons-benchmark/package.json b/packages/protons-benchmark/package.json index f9722ed..bccb9d8 100644 --- a/packages/protons-benchmark/package.json +++ b/packages/protons-benchmark/package.json @@ -24,7 +24,7 @@ "aegir": "^48.0.1", "benchmark": "^2.1.4", "pbjs": "^0.0.14", - "protobufjs": "^8.7.1", + "protobufjs": "^8.8.0", "protons": "^9.0.0", "protons-runtime": "^7.0.0", "uint8arraylist": "^3.0.0" diff --git a/packages/protons/package.json b/packages/protons/package.json index 5276e86..a44582f 100644 --- a/packages/protons/package.json +++ b/packages/protons/package.json @@ -145,7 +145,7 @@ "it-all": "^3.0.9", "long": "^5.3.2", "pbjs": "^0.0.14", - "protobufjs": "^8.7.1", + "protobufjs": "^8.8.0", "uint8arraylist": "^3.0.0", "uint8arrays": "^6.0.0" } diff --git a/packages/protons/src/fields/array-field.ts b/packages/protons/src/fields/array-field.ts index a79a1ca..e07a26d 100644 --- a/packages/protons/src/fields/array-field.ts +++ b/packages/protons/src/fields/array-field.ts @@ -1,6 +1,6 @@ import { Enum } from '../types/enum.ts' import { Message } from '../types/message.ts' -import { codecTypes, Field } from './field.ts' +import { CODEC_TYPES, codecTypes, Field } from './field.ts' import type { FieldDef } from './field.ts' import type { Parent, Type } from '../types/index.ts' @@ -12,13 +12,47 @@ export function isArrayFieldDef (obj?: any): obj is ArrayFieldDef { return obj?.rule === 'repeated' } +const PACKABLE_TYPES = [ + 'double', + 'float', + 'int32', + 'int64', + 'uint32', + 'uint64', + 'sint32', + 'sint64', + 'fixed32', + 'fixed64', + 'sfixed32', + 'sfixed64', + 'bool' +] + export class ArrayField extends Field { private lengthLimit?: number + private packed: boolean constructor (name: string, def: ArrayFieldDef, parent: Parent) { super(name, def, parent) this.lengthLimit = def.options?.['(protons.options).limit'] + + // console.info(parent) + + const type = parent.findType(this.type).pbType + const supportsPacked = PACKABLE_TYPES.indexOf(type) !== -1 + + // the default from protobuf3 onwards + this.packed = supportsPacked + + // check user override + if (def.options?.packed === false || def.options?.features?.repeated_field_encoding === 'EXPANDED') { + this.packed = false + } + + if (this.packed && !supportsPacked) { + throw new Error(`Repeated field "${name}" of type "${type}" cannot be packed as it is not a non-string/byte scalar type`) + } } getInterfaceField (parent: Parent, indent = ''): string { @@ -41,6 +75,20 @@ export class ArrayField extends Field { id = (this.id << 3) | codecTypes.enum } + if (this.packed) { + return ` + if (obj.${this.name} != null && obj.${this.name}.length > 0) { + w.uint32(${(this.id << 3) | CODEC_TYPES.LENGTH_DELIMITED}) + w.fork() + + for (const value of obj.${this.name}) { + ${type.getEncoder(this, 'value')} + } + + w.ldelim() + }` + } + return ` if (obj.${this.name} != null && obj.${this.name}.length > 0) { for (const value of obj.${this.name}) { @@ -69,6 +117,21 @@ export class ArrayField extends Field { const type: Type = parent.findType(this.type) + if (this.packed) { + this.parent.addImport('protons-runtime', 'reader') + + return `case ${this.id}: { + const b = r.bytes() + const r2 = reader(b) + + while (r2.pos < r2.len) {${limit.split('\n').join('\n ')} + obj.${this.name}.push(${type.getDecoder(this, undefined, 'r2')}) + } + + break + }` + } + return `case ${this.id}: {${limit} obj.${this.name}.push(${type.getDecoder(this)}) break @@ -99,6 +162,23 @@ export class ArrayField extends Field { field += '.' } + if (this.packed) { + this.parent.addImport('protons-runtime', 'reader') + + return `case ${this.id}: { + const b = r.bytes() + const r2 = reader(b) + + while (r2.pos < r2.len) {${limit.split('\n').join('\n ')} + ${type.getStreamingDecoder(this, `\`${field}\``, ' ', 'r2')} + + obj.${this.name}++ + } + + break + }` + } + return `case ${this.id}: {${limit} ${type.getStreamingDecoder(this, `\`${field}\``, ' ')} diff --git a/packages/protons/src/fields/field.ts b/packages/protons/src/fields/field.ts index 1c55723..1f44609 100644 --- a/packages/protons/src/fields/field.ts +++ b/packages/protons/src/fields/field.ts @@ -67,6 +67,7 @@ const defaultValueGeneratorsJsTypeOverrides: Record { proto3_optional?: boolean jstype?: 'string' | 'number' + packed?: boolean } export interface FieldDef { @@ -93,10 +94,12 @@ export class Field implements MessageField { public proto2Required: boolean public jsTypeOverride?: 'string' | 'number' public oneof?: string[] + protected parent: Parent constructor (name: string, def: FieldDef, parent: Parent) { this.id = def.id this.name = name + this.parent = parent // the default type for a message is unset so they are always optional // https://developers.google.com/protocol-buffers/docs/proto3#default diff --git a/packages/protons/src/types/enum.ts b/packages/protons/src/types/enum.ts index b8e3b1c..a170fde 100644 --- a/packages/protons/src/types/enum.ts +++ b/packages/protons/src/types/enum.ts @@ -50,22 +50,22 @@ export class Enum implements Type { } - getDecoder (field: Field): string { - return `${this.jsType}.codec().decode(reader)` + getDecoder (field: Field, indent?: string, reader = 'r'): string { + return `${this.jsType}.codec().decode(${reader})` } - getStreamingDecoder (field: Field, prefix: string, indent: ''): string { + getStreamingDecoder (field: Field, prefix: string, indent: '', reader = 'r'): string { if (field instanceof ArrayField) { return `yield { ${indent} field: ${prefix}, ${indent} index: obj.${field.name}, -${indent} value: ${this.jsType}.codec().decode(reader) +${indent} value: ${this.jsType}.codec().decode(${reader}) ${indent} }` } return `yield { ${indent} field: ${prefix}, -${indent} value: ${this.jsType}.codec().decode(reader) +${indent} value: ${this.jsType}.codec().decode(${reader}) ${indent} }` } diff --git a/packages/protons/src/types/index.ts b/packages/protons/src/types/index.ts index db02ec2..63834b0 100644 --- a/packages/protons/src/types/index.ts +++ b/packages/protons/src/types/index.ts @@ -6,8 +6,8 @@ export interface Type { jsType: string pbType: string init(module: Module): void - getDecoder(field: Field, indent?: string): string - getStreamingDecoder(field: Field, prefix: string, indent?: string): string + getDecoder(field: Field, indent?: string, reader?: string): string + getStreamingDecoder(field: Field, prefix: string, indent?: string, reader?: string): string getEncoder(field: Field, accessor: string): string getValueTest(field: Field, accessor: string): string } diff --git a/packages/protons/src/types/message.ts b/packages/protons/src/types/message.ts index d208d2f..145e4f0 100644 --- a/packages/protons/src/types/message.ts +++ b/packages/protons/src/types/message.ts @@ -165,7 +165,7 @@ export class Message implements Type { return this.parent.flags } - getDecoder (field: Field, indent = ''): string { + getDecoder (field: Field, indent = '', reader = 'r'): string { let opts = '' if (field instanceof MessageField) { @@ -184,10 +184,10 @@ ${indent} value: opts.limits?.${field.name}$value ${indent} }` } - return `${this.jsType}.codec().decode(reader, reader.uint32()${opts})` + return `${this.jsType}.codec().decode(${reader}, ${reader}.uint32()${opts})` } - getStreamingDecoder (field: Field, prefix: string, indent: ''): string { + getStreamingDecoder (field: Field, prefix: string, indent: '', reader = 'r'): string { let opts = '' if (field instanceof MessageField) { @@ -199,7 +199,7 @@ ${indent} }` ${indent} limits: opts.limits?.${field.name}$ ${indent} }` - return `for (const evt of ${this.jsType}.codec().stream(reader, reader.uint32(), ${prefix}${opts})) { + return `for (const evt of ${this.jsType}.codec().stream(${reader}, ${reader}.uint32(), ${prefix}${opts})) { ${indent} yield { ${indent} ...evt, ${indent} index: obj.${field.name} @@ -213,7 +213,7 @@ ${indent} value: opts.limits?.${field.name}$value ${indent} }` } - return `yield * ${this.jsType}.codec().stream(reader, reader.uint32(), ${prefix}${opts})` + return `yield * ${this.jsType}.codec().stream(${reader}, ${reader}.uint32(), ${prefix}${opts})` } getEncoder (field: Field, accessor: string): string { @@ -298,25 +298,25 @@ export interface ${this.pbType} { if (opts.lengthDelimited !== false) { w.ldelim() } - }, (reader, length, opts = {}) => { + }, (r, length, opts = {}) => { const obj: any = {${this.createDefaultObject()}} - const end = length == null ? reader.len : reader.pos + length + const end = length == null ? r.len : r.pos + length - while (reader.pos < end) { - const tag = reader.uint32() + while (r.pos < end) { + const tag = r.uint32() switch (tag >>> 3) {${this.formatFields(decodeFields, '\n ')} default: { - reader.skipType(tag & 7) + r.skipType(tag & 7) break } } } ${enforceOneOfDecoding === '' ? '' : `${enforceOneOfDecoding}\n`} return obj - }, function * (reader, length, prefix, opts = {}) { - ${this.createLimitObject()}const end = length == null ? reader.len : reader.pos + length + }, function * (r, length, prefix, opts = {}) { + ${this.createLimitObject()}const end = length == null ? r.len : r.pos + length if (prefix !== '.') { yield { @@ -326,12 +326,12 @@ ${enforceOneOfDecoding === '' ? '' : `${enforceOneOfDecoding}\n`} } } - while (reader.pos < end) { - const tag = reader.uint32() + while (r.pos < end) { + const tag = r.uint32() switch (tag >>> 3) {${this.formatFields(streamFields, '\n ')} default: { - reader.skipType(tag & 7) + r.skipType(tag & 7) break } } diff --git a/packages/protons/src/types/primitive.ts b/packages/protons/src/types/primitive.ts index 17ea8a4..c5751f8 100644 --- a/packages/protons/src/types/primitive.ts +++ b/packages/protons/src/types/primitive.ts @@ -2,71 +2,71 @@ import { ArrayField } from '../fields/array-field.ts' import type { Type } from './index.ts' import type { Field } from '../fields/field.ts' -const decoderGenerators: Record string> = { - bool: () => 'reader.bool()', - bytes: () => 'reader.bytes()', - double: () => 'reader.double()', - fixed32: () => 'reader.fixed32()', - fixed64: (jsTypeOverride) => { +const decoderGenerators: Record string> = { + bool: (_, reader = 'r') => `${reader}.bool()`, + bytes: (_, reader = 'r') => `${reader}.bytes()`, + double: (_, reader = 'r') => `${reader}.double()`, + fixed32: (_, reader = 'r') => `${reader}.fixed32()`, + fixed64: (jsTypeOverride, reader = 'r') => { if (jsTypeOverride === 'number') { - return 'reader.fixed64Number()' + return `${reader}.fixed64Number()` } if (jsTypeOverride === 'string') { - return 'reader.fixed64String()' + return `${reader}.fixed64String()` } - return 'reader.fixed64()' + return `${reader}.fixed64()` }, - float: () => 'reader.float()', - int32: () => 'reader.int32()', - int64: (jsTypeOverride) => { + float: (_, reader = 'r') => `${reader}.float()`, + int32: (_, reader = 'r') => `${reader}.int32()`, + int64: (jsTypeOverride, reader = 'r') => { if (jsTypeOverride === 'number') { - return 'reader.int64Number()' + return `${reader}.int64Number()` } if (jsTypeOverride === 'string') { - return 'reader.int64String()' + return `${reader}.int64String()` } - return 'reader.int64()' + return `${reader}.int64()` }, - sfixed32: () => 'reader.sfixed32()', - sfixed64: (jsTypeOverride) => { + sfixed32: (_, reader = 'r') => `${reader}.sfixed32()`, + sfixed64: (jsTypeOverride, reader = 'r') => { if (jsTypeOverride === 'number') { - return 'reader.sfixed64Number()' + return `${reader}.sfixed64Number()` } if (jsTypeOverride === 'string') { - return 'reader.sfixed64String()' + return `${reader}.sfixed64String()` } - return 'reader.sfixed64()' + return `${reader}.sfixed64()` }, - sint32: () => 'reader.sint32()', - sint64: (jsTypeOverride) => { + sint32: (_, reader = 'r') => `${reader}.sint32()`, + sint64: (jsTypeOverride, reader = 'r') => { if (jsTypeOverride === 'number') { - return 'reader.sint64Number()' + return `${reader}.sint64Number()` } if (jsTypeOverride === 'string') { - return 'reader.sint64String()' + return `${reader}.sint64String()` } - return 'reader.sint64()' + return `${reader}.sint64()` }, - string: () => 'reader.string()', - uint32: () => 'reader.uint32()', - uint64: (jsTypeOverride) => { + string: (_, reader = 'r') => `${reader}.string()`, + uint32: (_, reader = 'r') => `${reader}.uint32()`, + uint64: (jsTypeOverride, reader = 'r') => { if (jsTypeOverride === 'number') { - return 'reader.uint64Number()' + return `${reader}.uint64Number()` } if (jsTypeOverride === 'string') { - return 'reader.uint64String()' + return `${reader}.uint64String()` } - return 'reader.uint64()' + return `${reader}.uint64()` } } @@ -178,12 +178,12 @@ export class Primitive implements Type { } - getDecoder (field: Field): string { - return decoderGenerators[this.pbType](field.jsTypeOverride) + getDecoder (field: Field, indent = '', reader = 'r'): string { + return decoderGenerators[this.pbType](field.jsTypeOverride, reader) } - getStreamingDecoder (field: Field, prefix: string, indent = ''): string { - const generator = decoderGenerators[this.pbType](field.jsTypeOverride) + getStreamingDecoder (field: Field, prefix: string, indent = '', reader = 'r'): string { + const generator = decoderGenerators[this.pbType](field.jsTypeOverride, reader) if (field instanceof ArrayField) { return `yield { diff --git a/packages/protons/test/fixtures/basic.ts b/packages/protons/test/fixtures/basic.ts index 5c54b09..82ffee4 100644 --- a/packages/protons/test/fixtures/basic.ts +++ b/packages/protons/test/fixtures/basic.ts @@ -30,35 +30,35 @@ export namespace Basic { if (opts.lengthDelimited !== false) { w.ldelim() } - }, (reader, length, opts = {}) => { + }, (r, length, opts = {}) => { const obj: any = { num: 0 } - const end = length == null ? reader.len : reader.pos + length + const end = length == null ? r.len : r.pos + length - while (reader.pos < end) { - const tag = reader.uint32() + while (r.pos < end) { + const tag = r.uint32() switch (tag >>> 3) { case 1: { - obj.foo = reader.string() + obj.foo = r.string() break } case 2: { - obj.num = reader.int32() + obj.num = r.int32() break } default: { - reader.skipType(tag & 7) + r.skipType(tag & 7) break } } } return obj - }, function * (reader, length, prefix, opts = {}) { - const end = length == null ? reader.len : reader.pos + length + }, function * (r, length, prefix, opts = {}) { + const end = length == null ? r.len : r.pos + length if (prefix !== '.') { yield { @@ -68,26 +68,26 @@ export namespace Basic { } } - while (reader.pos < end) { - const tag = reader.uint32() + while (r.pos < end) { + const tag = r.uint32() switch (tag >>> 3) { case 1: { yield { field: `${prefix}foo`, - value: reader.string() + value: r.string() } break } case 2: { yield { field: `${prefix}num`, - value: reader.int32() + value: r.int32() } break } default: { - reader.skipType(tag & 7) + r.skipType(tag & 7) break } } @@ -144,25 +144,25 @@ export namespace Empty { if (opts.lengthDelimited !== false) { w.ldelim() } - }, (reader, length, opts = {}) => { + }, (r, length, opts = {}) => { const obj: any = {} - const end = length == null ? reader.len : reader.pos + length + const end = length == null ? r.len : r.pos + length - while (reader.pos < end) { - const tag = reader.uint32() + while (r.pos < end) { + const tag = r.uint32() switch (tag >>> 3) { default: { - reader.skipType(tag & 7) + r.skipType(tag & 7) break } } } return obj - }, function * (reader, length, prefix, opts = {}) { - const end = length == null ? reader.len : reader.pos + length + }, function * (r, length, prefix, opts = {}) { + const end = length == null ? r.len : r.pos + length if (prefix !== '.') { yield { @@ -172,12 +172,12 @@ export namespace Empty { } } - while (reader.pos < end) { - const tag = reader.uint32() + while (r.pos < end) { + const tag = r.uint32() switch (tag >>> 3) { default: { - reader.skipType(tag & 7) + r.skipType(tag & 7) break } } diff --git a/packages/protons/test/fixtures/bitswap.ts b/packages/protons/test/fixtures/bitswap.ts index e0452ed..64711e8 100644 --- a/packages/protons/test/fixtures/bitswap.ts +++ b/packages/protons/test/fixtures/bitswap.ts @@ -80,7 +80,7 @@ export namespace Message { if (opts.lengthDelimited !== false) { w.ldelim() } - }, (reader, length, opts = {}) => { + }, (r, length, opts = {}) => { const obj: any = { block: uint8ArrayAlloc(0), priority: 0, @@ -88,42 +88,42 @@ export namespace Message { sendDontHave: false } - const end = length == null ? reader.len : reader.pos + length + const end = length == null ? r.len : r.pos + length - while (reader.pos < end) { - const tag = reader.uint32() + while (r.pos < end) { + const tag = r.uint32() switch (tag >>> 3) { case 1: { - obj.block = reader.bytes() + obj.block = r.bytes() break } case 2: { - obj.priority = reader.int32() + obj.priority = r.int32() break } case 3: { - obj.cancel = reader.bool() + obj.cancel = r.bool() break } case 4: { - obj.wantType = Message.Wantlist.WantType.codec().decode(reader) + obj.wantType = Message.Wantlist.WantType.codec().decode(r) break } case 5: { - obj.sendDontHave = reader.bool() + obj.sendDontHave = r.bool() break } default: { - reader.skipType(tag & 7) + r.skipType(tag & 7) break } } } return obj - }, function * (reader, length, prefix, opts = {}) { - const end = length == null ? reader.len : reader.pos + length + }, function * (r, length, prefix, opts = {}) { + const end = length == null ? r.len : r.pos + length if (prefix !== '.') { yield { @@ -133,47 +133,47 @@ export namespace Message { } } - while (reader.pos < end) { - const tag = reader.uint32() + while (r.pos < end) { + const tag = r.uint32() switch (tag >>> 3) { case 1: { yield { field: `${prefix}block`, - value: reader.bytes() + value: r.bytes() } break } case 2: { yield { field: `${prefix}priority`, - value: reader.int32() + value: r.int32() } break } case 3: { yield { field: `${prefix}cancel`, - value: reader.bool() + value: r.bool() } break } case 4: { yield { field: `${prefix}wantType`, - value: Message.Wantlist.WantType.codec().decode(reader) + value: Message.Wantlist.WantType.codec().decode(r) } break } case 5: { yield { field: `${prefix}sendDontHave`, - value: reader.bool() + value: r.bool() } break } default: { - reader.skipType(tag & 7) + r.skipType(tag & 7) break } } @@ -254,16 +254,16 @@ export namespace Message { if (opts.lengthDelimited !== false) { w.ldelim() } - }, (reader, length, opts = {}) => { + }, (r, length, opts = {}) => { const obj: any = { entries: [], full: false } - const end = length == null ? reader.len : reader.pos + length + const end = length == null ? r.len : r.pos + length - while (reader.pos < end) { - const tag = reader.uint32() + while (r.pos < end) { + const tag = r.uint32() switch (tag >>> 3) { case 1: { @@ -271,29 +271,29 @@ export namespace Message { throw new MaxLengthError('Decode error - repeated field "entries" had too many elements') } - obj.entries.push(Message.Wantlist.Entry.codec().decode(reader, reader.uint32(), { + obj.entries.push(Message.Wantlist.Entry.codec().decode(r, r.uint32(), { limits: opts.limits?.entries$ })) break } case 2: { - obj.full = reader.bool() + obj.full = r.bool() break } default: { - reader.skipType(tag & 7) + r.skipType(tag & 7) break } } } return obj - }, function * (reader, length, prefix, opts = {}) { + }, function * (r, length, prefix, opts = {}) { const obj = { entries: 0 } - const end = length == null ? reader.len : reader.pos + length + const end = length == null ? r.len : r.pos + length if (prefix !== '.') { yield { @@ -303,8 +303,8 @@ export namespace Message { } } - while (reader.pos < end) { - const tag = reader.uint32() + while (r.pos < end) { + const tag = r.uint32() switch (tag >>> 3) { case 1: { @@ -312,7 +312,7 @@ export namespace Message { throw new MaxLengthError('Streaming decode error - repeated field "entries" had too many elements') } - for (const evt of Message.Wantlist.Entry.codec().stream(reader, reader.uint32(), `${prefix}entries[].`, { + for (const evt of Message.Wantlist.Entry.codec().stream(r, r.uint32(), `${prefix}entries[].`, { limits: opts.limits?.entries$ })) { yield { @@ -328,12 +328,12 @@ export namespace Message { case 2: { yield { field: `${prefix}full`, - value: reader.bool() + value: r.bool() } break } default: { - reader.skipType(tag & 7) + r.skipType(tag & 7) break } } @@ -442,36 +442,36 @@ export namespace Message { if (opts.lengthDelimited !== false) { w.ldelim() } - }, (reader, length, opts = {}) => { + }, (r, length, opts = {}) => { const obj: any = { prefix: uint8ArrayAlloc(0), data: uint8ArrayAlloc(0) } - const end = length == null ? reader.len : reader.pos + length + const end = length == null ? r.len : r.pos + length - while (reader.pos < end) { - const tag = reader.uint32() + while (r.pos < end) { + const tag = r.uint32() switch (tag >>> 3) { case 1: { - obj.prefix = reader.bytes() + obj.prefix = r.bytes() break } case 2: { - obj.data = reader.bytes() + obj.data = r.bytes() break } default: { - reader.skipType(tag & 7) + r.skipType(tag & 7) break } } } return obj - }, function * (reader, length, prefix, opts = {}) { - const end = length == null ? reader.len : reader.pos + length + }, function * (r, length, prefix, opts = {}) { + const end = length == null ? r.len : r.pos + length if (prefix !== '.') { yield { @@ -481,26 +481,26 @@ export namespace Message { } } - while (reader.pos < end) { - const tag = reader.uint32() + while (r.pos < end) { + const tag = r.uint32() switch (tag >>> 3) { case 1: { yield { field: `${prefix}prefix`, - value: reader.bytes() + value: r.bytes() } break } case 2: { yield { field: `${prefix}data`, - value: reader.bytes() + value: r.bytes() } break } default: { - reader.skipType(tag & 7) + r.skipType(tag & 7) break } } @@ -586,36 +586,36 @@ export namespace Message { if (opts.lengthDelimited !== false) { w.ldelim() } - }, (reader, length, opts = {}) => { + }, (r, length, opts = {}) => { const obj: any = { cid: uint8ArrayAlloc(0), type: BlockPresenceType.Have } - const end = length == null ? reader.len : reader.pos + length + const end = length == null ? r.len : r.pos + length - while (reader.pos < end) { - const tag = reader.uint32() + while (r.pos < end) { + const tag = r.uint32() switch (tag >>> 3) { case 1: { - obj.cid = reader.bytes() + obj.cid = r.bytes() break } case 2: { - obj.type = Message.BlockPresenceType.codec().decode(reader) + obj.type = Message.BlockPresenceType.codec().decode(r) break } default: { - reader.skipType(tag & 7) + r.skipType(tag & 7) break } } } return obj - }, function * (reader, length, prefix, opts = {}) { - const end = length == null ? reader.len : reader.pos + length + }, function * (r, length, prefix, opts = {}) { + const end = length == null ? r.len : r.pos + length if (prefix !== '.') { yield { @@ -625,26 +625,26 @@ export namespace Message { } } - while (reader.pos < end) { - const tag = reader.uint32() + while (r.pos < end) { + const tag = r.uint32() switch (tag >>> 3) { case 1: { yield { field: `${prefix}cid`, - value: reader.bytes() + value: r.bytes() } break } case 2: { yield { field: `${prefix}type`, - value: Message.BlockPresenceType.codec().decode(reader) + value: Message.BlockPresenceType.codec().decode(r) } break } default: { - reader.skipType(tag & 7) + r.skipType(tag & 7) break } } @@ -729,7 +729,7 @@ export namespace Message { if (opts.lengthDelimited !== false) { w.ldelim() } - }, (reader, length, opts = {}) => { + }, (r, length, opts = {}) => { const obj: any = { blocks: [], payload: [], @@ -737,14 +737,14 @@ export namespace Message { pendingBytes: 0 } - const end = length == null ? reader.len : reader.pos + length + const end = length == null ? r.len : r.pos + length - while (reader.pos < end) { - const tag = reader.uint32() + while (r.pos < end) { + const tag = r.uint32() switch (tag >>> 3) { case 1: { - obj.wantlist = Message.Wantlist.codec().decode(reader, reader.uint32(), { + obj.wantlist = Message.Wantlist.codec().decode(r, r.uint32(), { limits: opts.limits?.wantlist }) break @@ -754,7 +754,7 @@ export namespace Message { throw new MaxLengthError('Decode error - repeated field "blocks" had too many elements') } - obj.blocks.push(reader.bytes()) + obj.blocks.push(r.bytes()) break } case 3: { @@ -762,7 +762,7 @@ export namespace Message { throw new MaxLengthError('Decode error - repeated field "payload" had too many elements') } - obj.payload.push(Message.Block.codec().decode(reader, reader.uint32(), { + obj.payload.push(Message.Block.codec().decode(r, r.uint32(), { limits: opts.limits?.payload$ })) break @@ -772,31 +772,31 @@ export namespace Message { throw new MaxLengthError('Decode error - repeated field "blockPresences" had too many elements') } - obj.blockPresences.push(Message.BlockPresence.codec().decode(reader, reader.uint32(), { + obj.blockPresences.push(Message.BlockPresence.codec().decode(r, r.uint32(), { limits: opts.limits?.blockPresences$ })) break } case 5: { - obj.pendingBytes = reader.int32() + obj.pendingBytes = r.int32() break } default: { - reader.skipType(tag & 7) + r.skipType(tag & 7) break } } } return obj - }, function * (reader, length, prefix, opts = {}) { + }, function * (r, length, prefix, opts = {}) { const obj = { blocks: 0, payload: 0, blockPresences: 0 } - const end = length == null ? reader.len : reader.pos + length + const end = length == null ? r.len : r.pos + length if (prefix !== '.') { yield { @@ -806,12 +806,12 @@ export namespace Message { } } - while (reader.pos < end) { - const tag = reader.uint32() + while (r.pos < end) { + const tag = r.uint32() switch (tag >>> 3) { case 1: { - yield * Message.Wantlist.codec().stream(reader, reader.uint32(), `${prefix}wantlist.`, { + yield * Message.Wantlist.codec().stream(r, r.uint32(), `${prefix}wantlist.`, { limits: opts.limits?.wantlist }) @@ -825,7 +825,7 @@ export namespace Message { yield { field: `${prefix}blocks[]`, index: obj.blocks, - value: reader.bytes() + value: r.bytes() } obj.blocks++ @@ -837,7 +837,7 @@ export namespace Message { throw new MaxLengthError('Streaming decode error - repeated field "payload" had too many elements') } - for (const evt of Message.Block.codec().stream(reader, reader.uint32(), `${prefix}payload[].`, { + for (const evt of Message.Block.codec().stream(r, r.uint32(), `${prefix}payload[].`, { limits: opts.limits?.payload$ })) { yield { @@ -855,7 +855,7 @@ export namespace Message { throw new MaxLengthError('Streaming decode error - repeated field "blockPresences" had too many elements') } - for (const evt of Message.BlockPresence.codec().stream(reader, reader.uint32(), `${prefix}blockPresences[].`, { + for (const evt of Message.BlockPresence.codec().stream(r, r.uint32(), `${prefix}blockPresences[].`, { limits: opts.limits?.blockPresences$ })) { yield { @@ -871,12 +871,12 @@ export namespace Message { case 5: { yield { field: `${prefix}pendingBytes`, - value: reader.int32() + value: r.int32() } break } default: { - reader.skipType(tag & 7) + r.skipType(tag & 7) break } } diff --git a/packages/protons/test/fixtures/circuit.ts b/packages/protons/test/fixtures/circuit.ts index 74fffb6..bd898dd 100644 --- a/packages/protons/test/fixtures/circuit.ts +++ b/packages/protons/test/fixtures/circuit.ts @@ -105,20 +105,20 @@ export namespace CircuitRelay { if (opts.lengthDelimited !== false) { w.ldelim() } - }, (reader, length, opts = {}) => { + }, (r, length, opts = {}) => { const obj: any = { id: uint8ArrayAlloc(0), addrs: [] } - const end = length == null ? reader.len : reader.pos + length + const end = length == null ? r.len : r.pos + length - while (reader.pos < end) { - const tag = reader.uint32() + while (r.pos < end) { + const tag = r.uint32() switch (tag >>> 3) { case 1: { - obj.id = reader.bytes() + obj.id = r.bytes() break } case 2: { @@ -126,23 +126,23 @@ export namespace CircuitRelay { throw new MaxLengthError('Decode error - repeated field "addrs" had too many elements') } - obj.addrs.push(reader.bytes()) + obj.addrs.push(r.bytes()) break } default: { - reader.skipType(tag & 7) + r.skipType(tag & 7) break } } } return obj - }, function * (reader, length, prefix, opts = {}) { + }, function * (r, length, prefix, opts = {}) { const obj = { addrs: 0 } - const end = length == null ? reader.len : reader.pos + length + const end = length == null ? r.len : r.pos + length if (prefix !== '.') { yield { @@ -152,14 +152,14 @@ export namespace CircuitRelay { } } - while (reader.pos < end) { - const tag = reader.uint32() + while (r.pos < end) { + const tag = r.uint32() switch (tag >>> 3) { case 1: { yield { field: `${prefix}id`, - value: reader.bytes() + value: r.bytes() } break } @@ -171,7 +171,7 @@ export namespace CircuitRelay { yield { field: `${prefix}addrs[]`, index: obj.addrs, - value: reader.bytes() + value: r.bytes() } obj.addrs++ @@ -179,7 +179,7 @@ export namespace CircuitRelay { break } default: { - reader.skipType(tag & 7) + r.skipType(tag & 7) break } } @@ -254,45 +254,45 @@ export namespace CircuitRelay { if (opts.lengthDelimited !== false) { w.ldelim() } - }, (reader, length, opts = {}) => { + }, (r, length, opts = {}) => { const obj: any = {} - const end = length == null ? reader.len : reader.pos + length + const end = length == null ? r.len : r.pos + length - while (reader.pos < end) { - const tag = reader.uint32() + while (r.pos < end) { + const tag = r.uint32() switch (tag >>> 3) { case 1: { - obj.type = CircuitRelay.Type.codec().decode(reader) + obj.type = CircuitRelay.Type.codec().decode(r) break } case 2: { - obj.srcPeer = CircuitRelay.Peer.codec().decode(reader, reader.uint32(), { + obj.srcPeer = CircuitRelay.Peer.codec().decode(r, r.uint32(), { limits: opts.limits?.srcPeer }) break } case 3: { - obj.dstPeer = CircuitRelay.Peer.codec().decode(reader, reader.uint32(), { + obj.dstPeer = CircuitRelay.Peer.codec().decode(r, r.uint32(), { limits: opts.limits?.dstPeer }) break } case 4: { - obj.code = CircuitRelay.Status.codec().decode(reader) + obj.code = CircuitRelay.Status.codec().decode(r) break } default: { - reader.skipType(tag & 7) + r.skipType(tag & 7) break } } } return obj - }, function * (reader, length, prefix, opts = {}) { - const end = length == null ? reader.len : reader.pos + length + }, function * (r, length, prefix, opts = {}) { + const end = length == null ? r.len : r.pos + length if (prefix !== '.') { yield { @@ -302,26 +302,26 @@ export namespace CircuitRelay { } } - while (reader.pos < end) { - const tag = reader.uint32() + while (r.pos < end) { + const tag = r.uint32() switch (tag >>> 3) { case 1: { yield { field: `${prefix}type`, - value: CircuitRelay.Type.codec().decode(reader) + value: CircuitRelay.Type.codec().decode(r) } break } case 2: { - yield * CircuitRelay.Peer.codec().stream(reader, reader.uint32(), `${prefix}srcPeer.`, { + yield * CircuitRelay.Peer.codec().stream(r, r.uint32(), `${prefix}srcPeer.`, { limits: opts.limits?.srcPeer }) break } case 3: { - yield * CircuitRelay.Peer.codec().stream(reader, reader.uint32(), `${prefix}dstPeer.`, { + yield * CircuitRelay.Peer.codec().stream(r, r.uint32(), `${prefix}dstPeer.`, { limits: opts.limits?.dstPeer }) @@ -330,12 +330,12 @@ export namespace CircuitRelay { case 4: { yield { field: `${prefix}code`, - value: CircuitRelay.Status.codec().decode(reader) + value: CircuitRelay.Status.codec().decode(r) } break } default: { - reader.skipType(tag & 7) + r.skipType(tag & 7) break } } diff --git a/packages/protons/test/fixtures/custom-option-jstype.ts b/packages/protons/test/fixtures/custom-option-jstype.ts index 9cea0d0..0391228 100644 --- a/packages/protons/test/fixtures/custom-option-jstype.ts +++ b/packages/protons/test/fixtures/custom-option-jstype.ts @@ -1,4 +1,4 @@ -import { decodeMessage, encodeMessage, MaxLengthError, MaxSizeError, message, streamMessage } from 'protons-runtime' +import { decodeMessage, encodeMessage, MaxLengthError, MaxSizeError, message, reader, streamMessage } from 'protons-runtime' import type { Codec, DecodeOptions } from 'protons-runtime' import type { Uint8ArrayList } from 'uint8arraylist' @@ -42,36 +42,36 @@ export namespace CustomOptionNumber { if (opts.lengthDelimited !== false) { w.ldelim() } - }, (reader, length, opts = {}) => { + }, (r, length, opts = {}) => { const obj: any = { key: 0, value: 0 } - const end = length == null ? reader.len : reader.pos + length + const end = length == null ? r.len : r.pos + length - while (reader.pos < end) { - const tag = reader.uint32() + while (r.pos < end) { + const tag = r.uint32() switch (tag >>> 3) { case 1: { - obj.key = reader.int64Number() + obj.key = r.int64Number() break } case 2: { - obj.value = reader.int64Number() + obj.value = r.int64Number() break } default: { - reader.skipType(tag & 7) + r.skipType(tag & 7) break } } } return obj - }, function * (reader, length, prefix, opts = {}) { - const end = length == null ? reader.len : reader.pos + length + }, function * (r, length, prefix, opts = {}) { + const end = length == null ? r.len : r.pos + length if (prefix !== '.') { yield { @@ -81,26 +81,26 @@ export namespace CustomOptionNumber { } } - while (reader.pos < end) { - const tag = reader.uint32() + while (r.pos < end) { + const tag = r.uint32() switch (tag >>> 3) { case 1: { yield { field: `${prefix}key`, - value: reader.int64Number() + value: r.int64Number() } break } case 2: { yield { field: `${prefix}value`, - value: reader.int64Number() + value: r.int64Number() } break } default: { - reader.skipType(tag & 7) + r.skipType(tag & 7) break } } @@ -182,10 +182,14 @@ export namespace CustomOptionNumber { } if (obj.i64Array != null && obj.i64Array.length > 0) { + w.uint32(58) + w.fork() + for (const value of obj.i64Array) { - w.uint32(56) w.int64Number(value) } + + w.ldelim() } if (obj.i64Map != null && obj.i64Map.size > 0) { @@ -198,7 +202,7 @@ export namespace CustomOptionNumber { if (opts.lengthDelimited !== false) { w.ldelim() } - }, (reader, length, opts = {}) => { + }, (r, length, opts = {}) => { const obj: any = { num: 0, i64: 0, @@ -210,42 +214,48 @@ export namespace CustomOptionNumber { i64Map: new Map() } - const end = length == null ? reader.len : reader.pos + length + const end = length == null ? r.len : r.pos + length - while (reader.pos < end) { - const tag = reader.uint32() + while (r.pos < end) { + const tag = r.uint32() switch (tag >>> 3) { case 1: { - obj.num = reader.int32() + obj.num = r.int32() break } case 2: { - obj.i64 = reader.int64Number() + obj.i64 = r.int64Number() break } case 3: { - obj.ui64 = reader.uint64Number() + obj.ui64 = r.uint64Number() break } case 4: { - obj.si64 = reader.sint64Number() + obj.si64 = r.sint64Number() break } case 5: { - obj.f64 = reader.fixed64Number() + obj.f64 = r.fixed64Number() break } case 6: { - obj.sf64 = reader.sfixed64Number() + obj.sf64 = r.sfixed64Number() break } case 7: { - if (opts.limits?.i64Array != null && obj.i64Array.length === opts.limits.i64Array) { - throw new MaxLengthError('Decode error - repeated field "i64Array" had too many elements') + const b = r.bytes() + const r2 = reader(b) + + while (r2.pos < r2.len) { + if (opts.limits?.i64Array != null && obj.i64Array.length === opts.limits.i64Array) { + throw new MaxLengthError('Decode error - repeated field "i64Array" had too many elements') + } + + obj.i64Array.push(r2.int64Number()) } - obj.i64Array.push(reader.int64Number()) break } case 8: { @@ -253,7 +263,7 @@ export namespace CustomOptionNumber { throw new MaxSizeError('Decode error - map field "i64Map" had too many elements') } - const entry = CustomOptionNumber.CustomOptionNumber$i64MapEntry.codec().decode(reader, reader.uint32(), { + const entry = CustomOptionNumber.CustomOptionNumber$i64MapEntry.codec().decode(r, r.uint32(), { limits: { value: opts.limits?.i64Map$value } @@ -262,20 +272,20 @@ export namespace CustomOptionNumber { break } default: { - reader.skipType(tag & 7) + r.skipType(tag & 7) break } } } return obj - }, function * (reader, length, prefix, opts = {}) { + }, function * (r, length, prefix, opts = {}) { const obj = { i64Array: 0, i64Map: 0 } - const end = length == null ? reader.len : reader.pos + length + const end = length == null ? r.len : r.pos + length if (prefix !== '.') { yield { @@ -285,64 +295,69 @@ export namespace CustomOptionNumber { } } - while (reader.pos < end) { - const tag = reader.uint32() + while (r.pos < end) { + const tag = r.uint32() switch (tag >>> 3) { case 1: { yield { field: `${prefix}num`, - value: reader.int32() + value: r.int32() } break } case 2: { yield { field: `${prefix}i64`, - value: reader.int64Number() + value: r.int64Number() } break } case 3: { yield { field: `${prefix}ui64`, - value: reader.uint64Number() + value: r.uint64Number() } break } case 4: { yield { field: `${prefix}si64`, - value: reader.sint64Number() + value: r.sint64Number() } break } case 5: { yield { field: `${prefix}f64`, - value: reader.fixed64Number() + value: r.fixed64Number() } break } case 6: { yield { field: `${prefix}sf64`, - value: reader.sfixed64Number() + value: r.sfixed64Number() } break } case 7: { - if (opts.limits?.i64Array != null && obj.i64Array === opts.limits.i64Array) { - throw new MaxLengthError('Streaming decode error - repeated field "i64Array" had too many elements') - } + const b = r.bytes() + const r2 = reader(b) - yield { - field: `${prefix}i64Array[]`, - index: obj.i64Array, - value: reader.int64Number() - } + while (r2.pos < r2.len) { + if (opts.limits?.i64Array != null && obj.i64Array === opts.limits.i64Array) { + throw new MaxLengthError('Streaming decode error - repeated field "i64Array" had too many elements') + } - obj.i64Array++ + yield { + field: `${prefix}i64Array[]`, + index: obj.i64Array, + value: r2.int64Number() + } + + obj.i64Array++ + } break } @@ -351,7 +366,7 @@ export namespace CustomOptionNumber { throw new MaxLengthError('Decode error - map field "i64Map" had too many elements') } - yield * CustomOptionNumber.CustomOptionNumber$i64MapEntry.codec().stream(reader, reader.uint32(), `${prefix}i64Map{}.`, { + yield * CustomOptionNumber.CustomOptionNumber$i64MapEntry.codec().stream(r, r.uint32(), `${prefix}i64Map{}.`, { limits: { value: opts.limits?.i64Map$value } @@ -362,7 +377,7 @@ export namespace CustomOptionNumber { break } default: { - reader.skipType(tag & 7) + r.skipType(tag & 7) break } } @@ -476,36 +491,36 @@ export namespace CustomOptionString { if (opts.lengthDelimited !== false) { w.ldelim() } - }, (reader, length, opts = {}) => { + }, (r, length, opts = {}) => { const obj: any = { key: '', value: '' } - const end = length == null ? reader.len : reader.pos + length + const end = length == null ? r.len : r.pos + length - while (reader.pos < end) { - const tag = reader.uint32() + while (r.pos < end) { + const tag = r.uint32() switch (tag >>> 3) { case 1: { - obj.key = reader.int64String() + obj.key = r.int64String() break } case 2: { - obj.value = reader.int64String() + obj.value = r.int64String() break } default: { - reader.skipType(tag & 7) + r.skipType(tag & 7) break } } } return obj - }, function * (reader, length, prefix, opts = {}) { - const end = length == null ? reader.len : reader.pos + length + }, function * (r, length, prefix, opts = {}) { + const end = length == null ? r.len : r.pos + length if (prefix !== '.') { yield { @@ -515,26 +530,26 @@ export namespace CustomOptionString { } } - while (reader.pos < end) { - const tag = reader.uint32() + while (r.pos < end) { + const tag = r.uint32() switch (tag >>> 3) { case 1: { yield { field: `${prefix}key`, - value: reader.int64String() + value: r.int64String() } break } case 2: { yield { field: `${prefix}value`, - value: reader.int64String() + value: r.int64String() } break } default: { - reader.skipType(tag & 7) + r.skipType(tag & 7) break } } @@ -616,10 +631,14 @@ export namespace CustomOptionString { } if (obj.i64Array != null && obj.i64Array.length > 0) { + w.uint32(58) + w.fork() + for (const value of obj.i64Array) { - w.uint32(56) w.int64String(value) } + + w.ldelim() } if (obj.i64Map != null && obj.i64Map.size > 0) { @@ -632,7 +651,7 @@ export namespace CustomOptionString { if (opts.lengthDelimited !== false) { w.ldelim() } - }, (reader, length, opts = {}) => { + }, (r, length, opts = {}) => { const obj: any = { num: 0, i64: '', @@ -644,42 +663,48 @@ export namespace CustomOptionString { i64Map: new Map() } - const end = length == null ? reader.len : reader.pos + length + const end = length == null ? r.len : r.pos + length - while (reader.pos < end) { - const tag = reader.uint32() + while (r.pos < end) { + const tag = r.uint32() switch (tag >>> 3) { case 1: { - obj.num = reader.int32() + obj.num = r.int32() break } case 2: { - obj.i64 = reader.int64String() + obj.i64 = r.int64String() break } case 3: { - obj.ui64 = reader.uint64String() + obj.ui64 = r.uint64String() break } case 4: { - obj.si64 = reader.sint64String() + obj.si64 = r.sint64String() break } case 5: { - obj.f64 = reader.fixed64String() + obj.f64 = r.fixed64String() break } case 6: { - obj.sf64 = reader.sfixed64String() + obj.sf64 = r.sfixed64String() break } case 7: { - if (opts.limits?.i64Array != null && obj.i64Array.length === opts.limits.i64Array) { - throw new MaxLengthError('Decode error - repeated field "i64Array" had too many elements') + const b = r.bytes() + const r2 = reader(b) + + while (r2.pos < r2.len) { + if (opts.limits?.i64Array != null && obj.i64Array.length === opts.limits.i64Array) { + throw new MaxLengthError('Decode error - repeated field "i64Array" had too many elements') + } + + obj.i64Array.push(r2.int64String()) } - obj.i64Array.push(reader.int64String()) break } case 8: { @@ -687,7 +712,7 @@ export namespace CustomOptionString { throw new MaxSizeError('Decode error - map field "i64Map" had too many elements') } - const entry = CustomOptionString.CustomOptionString$i64MapEntry.codec().decode(reader, reader.uint32(), { + const entry = CustomOptionString.CustomOptionString$i64MapEntry.codec().decode(r, r.uint32(), { limits: { value: opts.limits?.i64Map$value } @@ -696,20 +721,20 @@ export namespace CustomOptionString { break } default: { - reader.skipType(tag & 7) + r.skipType(tag & 7) break } } } return obj - }, function * (reader, length, prefix, opts = {}) { + }, function * (r, length, prefix, opts = {}) { const obj = { i64Array: 0, i64Map: 0 } - const end = length == null ? reader.len : reader.pos + length + const end = length == null ? r.len : r.pos + length if (prefix !== '.') { yield { @@ -719,64 +744,69 @@ export namespace CustomOptionString { } } - while (reader.pos < end) { - const tag = reader.uint32() + while (r.pos < end) { + const tag = r.uint32() switch (tag >>> 3) { case 1: { yield { field: `${prefix}num`, - value: reader.int32() + value: r.int32() } break } case 2: { yield { field: `${prefix}i64`, - value: reader.int64String() + value: r.int64String() } break } case 3: { yield { field: `${prefix}ui64`, - value: reader.uint64String() + value: r.uint64String() } break } case 4: { yield { field: `${prefix}si64`, - value: reader.sint64String() + value: r.sint64String() } break } case 5: { yield { field: `${prefix}f64`, - value: reader.fixed64String() + value: r.fixed64String() } break } case 6: { yield { field: `${prefix}sf64`, - value: reader.sfixed64String() + value: r.sfixed64String() } break } case 7: { - if (opts.limits?.i64Array != null && obj.i64Array === opts.limits.i64Array) { - throw new MaxLengthError('Streaming decode error - repeated field "i64Array" had too many elements') - } + const b = r.bytes() + const r2 = reader(b) - yield { - field: `${prefix}i64Array[]`, - index: obj.i64Array, - value: reader.int64String() - } + while (r2.pos < r2.len) { + if (opts.limits?.i64Array != null && obj.i64Array === opts.limits.i64Array) { + throw new MaxLengthError('Streaming decode error - repeated field "i64Array" had too many elements') + } - obj.i64Array++ + yield { + field: `${prefix}i64Array[]`, + index: obj.i64Array, + value: r2.int64String() + } + + obj.i64Array++ + } break } @@ -785,7 +815,7 @@ export namespace CustomOptionString { throw new MaxLengthError('Decode error - map field "i64Map" had too many elements') } - yield * CustomOptionString.CustomOptionString$i64MapEntry.codec().stream(reader, reader.uint32(), `${prefix}i64Map{}.`, { + yield * CustomOptionString.CustomOptionString$i64MapEntry.codec().stream(r, r.uint32(), `${prefix}i64Map{}.`, { limits: { value: opts.limits?.i64Map$value } @@ -796,7 +826,7 @@ export namespace CustomOptionString { break } default: { - reader.skipType(tag & 7) + r.skipType(tag & 7) break } } diff --git a/packages/protons/test/fixtures/daemon.ts b/packages/protons/test/fixtures/daemon.ts index 1a0ec8a..a3f8144 100644 --- a/packages/protons/test/fixtures/daemon.ts +++ b/packages/protons/test/fixtures/daemon.ts @@ -105,79 +105,79 @@ export namespace Request { if (opts.lengthDelimited !== false) { w.ldelim() } - }, (reader, length, opts = {}) => { + }, (r, length, opts = {}) => { const obj: any = { type: Type.IDENTIFY } - const end = length == null ? reader.len : reader.pos + length + const end = length == null ? r.len : r.pos + length - while (reader.pos < end) { - const tag = reader.uint32() + while (r.pos < end) { + const tag = r.uint32() switch (tag >>> 3) { case 1: { - obj.type = Request.Type.codec().decode(reader) + obj.type = Request.Type.codec().decode(r) break } case 2: { - obj.connect = ConnectRequest.codec().decode(reader, reader.uint32(), { + obj.connect = ConnectRequest.codec().decode(r, r.uint32(), { limits: opts.limits?.connect }) break } case 3: { - obj.streamOpen = StreamOpenRequest.codec().decode(reader, reader.uint32(), { + obj.streamOpen = StreamOpenRequest.codec().decode(r, r.uint32(), { limits: opts.limits?.streamOpen }) break } case 4: { - obj.streamHandler = StreamHandlerRequest.codec().decode(reader, reader.uint32(), { + obj.streamHandler = StreamHandlerRequest.codec().decode(r, r.uint32(), { limits: opts.limits?.streamHandler }) break } case 5: { - obj.dht = DHTRequest.codec().decode(reader, reader.uint32(), { + obj.dht = DHTRequest.codec().decode(r, r.uint32(), { limits: opts.limits?.dht }) break } case 6: { - obj.connManager = ConnManagerRequest.codec().decode(reader, reader.uint32(), { + obj.connManager = ConnManagerRequest.codec().decode(r, r.uint32(), { limits: opts.limits?.connManager }) break } case 7: { - obj.disconnect = DisconnectRequest.codec().decode(reader, reader.uint32(), { + obj.disconnect = DisconnectRequest.codec().decode(r, r.uint32(), { limits: opts.limits?.disconnect }) break } case 8: { - obj.pubsub = PSRequest.codec().decode(reader, reader.uint32(), { + obj.pubsub = PSRequest.codec().decode(r, r.uint32(), { limits: opts.limits?.pubsub }) break } case 9: { - obj.peerStore = PeerstoreRequest.codec().decode(reader, reader.uint32(), { + obj.peerStore = PeerstoreRequest.codec().decode(r, r.uint32(), { limits: opts.limits?.peerStore }) break } default: { - reader.skipType(tag & 7) + r.skipType(tag & 7) break } } } return obj - }, function * (reader, length, prefix, opts = {}) { - const end = length == null ? reader.len : reader.pos + length + }, function * (r, length, prefix, opts = {}) { + const end = length == null ? r.len : r.pos + length if (prefix !== '.') { yield { @@ -187,75 +187,75 @@ export namespace Request { } } - while (reader.pos < end) { - const tag = reader.uint32() + while (r.pos < end) { + const tag = r.uint32() switch (tag >>> 3) { case 1: { yield { field: `${prefix}type`, - value: Request.Type.codec().decode(reader) + value: Request.Type.codec().decode(r) } break } case 2: { - yield * ConnectRequest.codec().stream(reader, reader.uint32(), `${prefix}connect.`, { + yield * ConnectRequest.codec().stream(r, r.uint32(), `${prefix}connect.`, { limits: opts.limits?.connect }) break } case 3: { - yield * StreamOpenRequest.codec().stream(reader, reader.uint32(), `${prefix}streamOpen.`, { + yield * StreamOpenRequest.codec().stream(r, r.uint32(), `${prefix}streamOpen.`, { limits: opts.limits?.streamOpen }) break } case 4: { - yield * StreamHandlerRequest.codec().stream(reader, reader.uint32(), `${prefix}streamHandler.`, { + yield * StreamHandlerRequest.codec().stream(r, r.uint32(), `${prefix}streamHandler.`, { limits: opts.limits?.streamHandler }) break } case 5: { - yield * DHTRequest.codec().stream(reader, reader.uint32(), `${prefix}dht.`, { + yield * DHTRequest.codec().stream(r, r.uint32(), `${prefix}dht.`, { limits: opts.limits?.dht }) break } case 6: { - yield * ConnManagerRequest.codec().stream(reader, reader.uint32(), `${prefix}connManager.`, { + yield * ConnManagerRequest.codec().stream(r, r.uint32(), `${prefix}connManager.`, { limits: opts.limits?.connManager }) break } case 7: { - yield * DisconnectRequest.codec().stream(reader, reader.uint32(), `${prefix}disconnect.`, { + yield * DisconnectRequest.codec().stream(r, r.uint32(), `${prefix}disconnect.`, { limits: opts.limits?.disconnect }) break } case 8: { - yield * PSRequest.codec().stream(reader, reader.uint32(), `${prefix}pubsub.`, { + yield * PSRequest.codec().stream(r, r.uint32(), `${prefix}pubsub.`, { limits: opts.limits?.pubsub }) break } case 9: { - yield * PeerstoreRequest.codec().stream(reader, reader.uint32(), `${prefix}peerStore.`, { + yield * PeerstoreRequest.codec().stream(r, r.uint32(), `${prefix}peerStore.`, { limits: opts.limits?.peerStore }) break } default: { - reader.skipType(tag & 7) + r.skipType(tag & 7) break } } @@ -588,42 +588,42 @@ export namespace Response { if (opts.lengthDelimited !== false) { w.ldelim() } - }, (reader, length, opts = {}) => { + }, (r, length, opts = {}) => { const obj: any = { type: Type.OK, peers: [] } - const end = length == null ? reader.len : reader.pos + length + const end = length == null ? r.len : r.pos + length - while (reader.pos < end) { - const tag = reader.uint32() + while (r.pos < end) { + const tag = r.uint32() switch (tag >>> 3) { case 1: { - obj.type = Response.Type.codec().decode(reader) + obj.type = Response.Type.codec().decode(r) break } case 2: { - obj.error = ErrorResponse.codec().decode(reader, reader.uint32(), { + obj.error = ErrorResponse.codec().decode(r, r.uint32(), { limits: opts.limits?.error }) break } case 3: { - obj.streamInfo = StreamInfo.codec().decode(reader, reader.uint32(), { + obj.streamInfo = StreamInfo.codec().decode(r, r.uint32(), { limits: opts.limits?.streamInfo }) break } case 4: { - obj.identify = IdentifyResponse.codec().decode(reader, reader.uint32(), { + obj.identify = IdentifyResponse.codec().decode(r, r.uint32(), { limits: opts.limits?.identify }) break } case 5: { - obj.dht = DHTResponse.codec().decode(reader, reader.uint32(), { + obj.dht = DHTResponse.codec().decode(r, r.uint32(), { limits: opts.limits?.dht }) break @@ -633,37 +633,37 @@ export namespace Response { throw new MaxLengthError('Decode error - repeated field "peers" had too many elements') } - obj.peers.push(PeerInfo.codec().decode(reader, reader.uint32(), { + obj.peers.push(PeerInfo.codec().decode(r, r.uint32(), { limits: opts.limits?.peers$ })) break } case 7: { - obj.pubsub = PSResponse.codec().decode(reader, reader.uint32(), { + obj.pubsub = PSResponse.codec().decode(r, r.uint32(), { limits: opts.limits?.pubsub }) break } case 8: { - obj.peerStore = PeerstoreResponse.codec().decode(reader, reader.uint32(), { + obj.peerStore = PeerstoreResponse.codec().decode(r, r.uint32(), { limits: opts.limits?.peerStore }) break } default: { - reader.skipType(tag & 7) + r.skipType(tag & 7) break } } } return obj - }, function * (reader, length, prefix, opts = {}) { + }, function * (r, length, prefix, opts = {}) { const obj = { peers: 0 } - const end = length == null ? reader.len : reader.pos + length + const end = length == null ? r.len : r.pos + length if (prefix !== '.') { yield { @@ -673,40 +673,40 @@ export namespace Response { } } - while (reader.pos < end) { - const tag = reader.uint32() + while (r.pos < end) { + const tag = r.uint32() switch (tag >>> 3) { case 1: { yield { field: `${prefix}type`, - value: Response.Type.codec().decode(reader) + value: Response.Type.codec().decode(r) } break } case 2: { - yield * ErrorResponse.codec().stream(reader, reader.uint32(), `${prefix}error.`, { + yield * ErrorResponse.codec().stream(r, r.uint32(), `${prefix}error.`, { limits: opts.limits?.error }) break } case 3: { - yield * StreamInfo.codec().stream(reader, reader.uint32(), `${prefix}streamInfo.`, { + yield * StreamInfo.codec().stream(r, r.uint32(), `${prefix}streamInfo.`, { limits: opts.limits?.streamInfo }) break } case 4: { - yield * IdentifyResponse.codec().stream(reader, reader.uint32(), `${prefix}identify.`, { + yield * IdentifyResponse.codec().stream(r, r.uint32(), `${prefix}identify.`, { limits: opts.limits?.identify }) break } case 5: { - yield * DHTResponse.codec().stream(reader, reader.uint32(), `${prefix}dht.`, { + yield * DHTResponse.codec().stream(r, r.uint32(), `${prefix}dht.`, { limits: opts.limits?.dht }) @@ -717,7 +717,7 @@ export namespace Response { throw new MaxLengthError('Streaming decode error - repeated field "peers" had too many elements') } - for (const evt of PeerInfo.codec().stream(reader, reader.uint32(), `${prefix}peers[].`, { + for (const evt of PeerInfo.codec().stream(r, r.uint32(), `${prefix}peers[].`, { limits: opts.limits?.peers$ })) { yield { @@ -731,21 +731,21 @@ export namespace Response { break } case 7: { - yield * PSResponse.codec().stream(reader, reader.uint32(), `${prefix}pubsub.`, { + yield * PSResponse.codec().stream(r, r.uint32(), `${prefix}pubsub.`, { limits: opts.limits?.pubsub }) break } case 8: { - yield * PeerstoreResponse.codec().stream(reader, reader.uint32(), `${prefix}peerStore.`, { + yield * PeerstoreResponse.codec().stream(r, r.uint32(), `${prefix}peerStore.`, { limits: opts.limits?.peerStore }) break } default: { - reader.skipType(tag & 7) + r.skipType(tag & 7) break } } @@ -999,20 +999,20 @@ export namespace IdentifyResponse { if (opts.lengthDelimited !== false) { w.ldelim() } - }, (reader, length, opts = {}) => { + }, (r, length, opts = {}) => { const obj: any = { id: uint8ArrayAlloc(0), addrs: [] } - const end = length == null ? reader.len : reader.pos + length + const end = length == null ? r.len : r.pos + length - while (reader.pos < end) { - const tag = reader.uint32() + while (r.pos < end) { + const tag = r.uint32() switch (tag >>> 3) { case 1: { - obj.id = reader.bytes() + obj.id = r.bytes() break } case 2: { @@ -1020,23 +1020,23 @@ export namespace IdentifyResponse { throw new MaxLengthError('Decode error - repeated field "addrs" had too many elements') } - obj.addrs.push(reader.bytes()) + obj.addrs.push(r.bytes()) break } default: { - reader.skipType(tag & 7) + r.skipType(tag & 7) break } } } return obj - }, function * (reader, length, prefix, opts = {}) { + }, function * (r, length, prefix, opts = {}) { const obj = { addrs: 0 } - const end = length == null ? reader.len : reader.pos + length + const end = length == null ? r.len : r.pos + length if (prefix !== '.') { yield { @@ -1046,14 +1046,14 @@ export namespace IdentifyResponse { } } - while (reader.pos < end) { - const tag = reader.uint32() + while (r.pos < end) { + const tag = r.uint32() switch (tag >>> 3) { case 1: { yield { field: `${prefix}id`, - value: reader.bytes() + value: r.bytes() } break } @@ -1065,7 +1065,7 @@ export namespace IdentifyResponse { yield { field: `${prefix}addrs[]`, index: obj.addrs, - value: reader.bytes() + value: r.bytes() } obj.addrs++ @@ -1073,7 +1073,7 @@ export namespace IdentifyResponse { break } default: { - reader.skipType(tag & 7) + r.skipType(tag & 7) break } } @@ -1152,20 +1152,20 @@ export namespace ConnectRequest { if (opts.lengthDelimited !== false) { w.ldelim() } - }, (reader, length, opts = {}) => { + }, (r, length, opts = {}) => { const obj: any = { peer: uint8ArrayAlloc(0), addrs: [] } - const end = length == null ? reader.len : reader.pos + length + const end = length == null ? r.len : r.pos + length - while (reader.pos < end) { - const tag = reader.uint32() + while (r.pos < end) { + const tag = r.uint32() switch (tag >>> 3) { case 1: { - obj.peer = reader.bytes() + obj.peer = r.bytes() break } case 2: { @@ -1173,27 +1173,27 @@ export namespace ConnectRequest { throw new MaxLengthError('Decode error - repeated field "addrs" had too many elements') } - obj.addrs.push(reader.bytes()) + obj.addrs.push(r.bytes()) break } case 3: { - obj.timeout = reader.int64() + obj.timeout = r.int64() break } default: { - reader.skipType(tag & 7) + r.skipType(tag & 7) break } } } return obj - }, function * (reader, length, prefix, opts = {}) { + }, function * (r, length, prefix, opts = {}) { const obj = { addrs: 0 } - const end = length == null ? reader.len : reader.pos + length + const end = length == null ? r.len : r.pos + length if (prefix !== '.') { yield { @@ -1203,14 +1203,14 @@ export namespace ConnectRequest { } } - while (reader.pos < end) { - const tag = reader.uint32() + while (r.pos < end) { + const tag = r.uint32() switch (tag >>> 3) { case 1: { yield { field: `${prefix}peer`, - value: reader.bytes() + value: r.bytes() } break } @@ -1222,7 +1222,7 @@ export namespace ConnectRequest { yield { field: `${prefix}addrs[]`, index: obj.addrs, - value: reader.bytes() + value: r.bytes() } obj.addrs++ @@ -1232,12 +1232,12 @@ export namespace ConnectRequest { case 3: { yield { field: `${prefix}timeout`, - value: reader.int64() + value: r.int64() } break } default: { - reader.skipType(tag & 7) + r.skipType(tag & 7) break } } @@ -1321,20 +1321,20 @@ export namespace StreamOpenRequest { if (opts.lengthDelimited !== false) { w.ldelim() } - }, (reader, length, opts = {}) => { + }, (r, length, opts = {}) => { const obj: any = { peer: uint8ArrayAlloc(0), proto: [] } - const end = length == null ? reader.len : reader.pos + length + const end = length == null ? r.len : r.pos + length - while (reader.pos < end) { - const tag = reader.uint32() + while (r.pos < end) { + const tag = r.uint32() switch (tag >>> 3) { case 1: { - obj.peer = reader.bytes() + obj.peer = r.bytes() break } case 2: { @@ -1342,27 +1342,27 @@ export namespace StreamOpenRequest { throw new MaxLengthError('Decode error - repeated field "proto" had too many elements') } - obj.proto.push(reader.string()) + obj.proto.push(r.string()) break } case 3: { - obj.timeout = reader.int64() + obj.timeout = r.int64() break } default: { - reader.skipType(tag & 7) + r.skipType(tag & 7) break } } } return obj - }, function * (reader, length, prefix, opts = {}) { + }, function * (r, length, prefix, opts = {}) { const obj = { proto: 0 } - const end = length == null ? reader.len : reader.pos + length + const end = length == null ? r.len : r.pos + length if (prefix !== '.') { yield { @@ -1372,14 +1372,14 @@ export namespace StreamOpenRequest { } } - while (reader.pos < end) { - const tag = reader.uint32() + while (r.pos < end) { + const tag = r.uint32() switch (tag >>> 3) { case 1: { yield { field: `${prefix}peer`, - value: reader.bytes() + value: r.bytes() } break } @@ -1391,7 +1391,7 @@ export namespace StreamOpenRequest { yield { field: `${prefix}proto[]`, index: obj.proto, - value: reader.string() + value: r.string() } obj.proto++ @@ -1401,12 +1401,12 @@ export namespace StreamOpenRequest { case 3: { yield { field: `${prefix}timeout`, - value: reader.int64() + value: r.int64() } break } default: { - reader.skipType(tag & 7) + r.skipType(tag & 7) break } } @@ -1484,20 +1484,20 @@ export namespace StreamHandlerRequest { if (opts.lengthDelimited !== false) { w.ldelim() } - }, (reader, length, opts = {}) => { + }, (r, length, opts = {}) => { const obj: any = { addr: uint8ArrayAlloc(0), proto: [] } - const end = length == null ? reader.len : reader.pos + length + const end = length == null ? r.len : r.pos + length - while (reader.pos < end) { - const tag = reader.uint32() + while (r.pos < end) { + const tag = r.uint32() switch (tag >>> 3) { case 1: { - obj.addr = reader.bytes() + obj.addr = r.bytes() break } case 2: { @@ -1505,23 +1505,23 @@ export namespace StreamHandlerRequest { throw new MaxLengthError('Decode error - repeated field "proto" had too many elements') } - obj.proto.push(reader.string()) + obj.proto.push(r.string()) break } default: { - reader.skipType(tag & 7) + r.skipType(tag & 7) break } } } return obj - }, function * (reader, length, prefix, opts = {}) { + }, function * (r, length, prefix, opts = {}) { const obj = { proto: 0 } - const end = length == null ? reader.len : reader.pos + length + const end = length == null ? r.len : r.pos + length if (prefix !== '.') { yield { @@ -1531,14 +1531,14 @@ export namespace StreamHandlerRequest { } } - while (reader.pos < end) { - const tag = reader.uint32() + while (r.pos < end) { + const tag = r.uint32() switch (tag >>> 3) { case 1: { yield { field: `${prefix}addr`, - value: reader.bytes() + value: r.bytes() } break } @@ -1550,7 +1550,7 @@ export namespace StreamHandlerRequest { yield { field: `${prefix}proto[]`, index: obj.proto, - value: reader.string() + value: r.string() } obj.proto++ @@ -1558,7 +1558,7 @@ export namespace StreamHandlerRequest { break } default: { - reader.skipType(tag & 7) + r.skipType(tag & 7) break } } @@ -1623,31 +1623,31 @@ export namespace ErrorResponse { if (opts.lengthDelimited !== false) { w.ldelim() } - }, (reader, length, opts = {}) => { + }, (r, length, opts = {}) => { const obj: any = { msg: '' } - const end = length == null ? reader.len : reader.pos + length + const end = length == null ? r.len : r.pos + length - while (reader.pos < end) { - const tag = reader.uint32() + while (r.pos < end) { + const tag = r.uint32() switch (tag >>> 3) { case 1: { - obj.msg = reader.string() + obj.msg = r.string() break } default: { - reader.skipType(tag & 7) + r.skipType(tag & 7) break } } } return obj - }, function * (reader, length, prefix, opts = {}) { - const end = length == null ? reader.len : reader.pos + length + }, function * (r, length, prefix, opts = {}) { + const end = length == null ? r.len : r.pos + length if (prefix !== '.') { yield { @@ -1657,19 +1657,19 @@ export namespace ErrorResponse { } } - while (reader.pos < end) { - const tag = reader.uint32() + while (r.pos < end) { + const tag = r.uint32() switch (tag >>> 3) { case 1: { yield { field: `${prefix}msg`, - value: reader.string() + value: r.string() } break } default: { - reader.skipType(tag & 7) + r.skipType(tag & 7) break } } @@ -1740,41 +1740,41 @@ export namespace StreamInfo { if (opts.lengthDelimited !== false) { w.ldelim() } - }, (reader, length, opts = {}) => { + }, (r, length, opts = {}) => { const obj: any = { peer: uint8ArrayAlloc(0), addr: uint8ArrayAlloc(0), proto: '' } - const end = length == null ? reader.len : reader.pos + length + const end = length == null ? r.len : r.pos + length - while (reader.pos < end) { - const tag = reader.uint32() + while (r.pos < end) { + const tag = r.uint32() switch (tag >>> 3) { case 1: { - obj.peer = reader.bytes() + obj.peer = r.bytes() break } case 2: { - obj.addr = reader.bytes() + obj.addr = r.bytes() break } case 3: { - obj.proto = reader.string() + obj.proto = r.string() break } default: { - reader.skipType(tag & 7) + r.skipType(tag & 7) break } } } return obj - }, function * (reader, length, prefix, opts = {}) { - const end = length == null ? reader.len : reader.pos + length + }, function * (r, length, prefix, opts = {}) { + const end = length == null ? r.len : r.pos + length if (prefix !== '.') { yield { @@ -1784,33 +1784,33 @@ export namespace StreamInfo { } } - while (reader.pos < end) { - const tag = reader.uint32() + while (r.pos < end) { + const tag = r.uint32() switch (tag >>> 3) { case 1: { yield { field: `${prefix}peer`, - value: reader.bytes() + value: r.bytes() } break } case 2: { yield { field: `${prefix}addr`, - value: reader.bytes() + value: r.bytes() } break } case 3: { yield { field: `${prefix}proto`, - value: reader.string() + value: r.string() } break } default: { - reader.skipType(tag & 7) + r.skipType(tag & 7) break } } @@ -1945,55 +1945,55 @@ export namespace DHTRequest { if (opts.lengthDelimited !== false) { w.ldelim() } - }, (reader, length, opts = {}) => { + }, (r, length, opts = {}) => { const obj: any = { type: Type.FIND_PEER } - const end = length == null ? reader.len : reader.pos + length + const end = length == null ? r.len : r.pos + length - while (reader.pos < end) { - const tag = reader.uint32() + while (r.pos < end) { + const tag = r.uint32() switch (tag >>> 3) { case 1: { - obj.type = DHTRequest.Type.codec().decode(reader) + obj.type = DHTRequest.Type.codec().decode(r) break } case 2: { - obj.peer = reader.bytes() + obj.peer = r.bytes() break } case 3: { - obj.cid = reader.bytes() + obj.cid = r.bytes() break } case 4: { - obj.key = reader.bytes() + obj.key = r.bytes() break } case 5: { - obj.value = reader.bytes() + obj.value = r.bytes() break } case 6: { - obj.count = reader.int32() + obj.count = r.int32() break } case 7: { - obj.timeout = reader.int64() + obj.timeout = r.int64() break } default: { - reader.skipType(tag & 7) + r.skipType(tag & 7) break } } } return obj - }, function * (reader, length, prefix, opts = {}) { - const end = length == null ? reader.len : reader.pos + length + }, function * (r, length, prefix, opts = {}) { + const end = length == null ? r.len : r.pos + length if (prefix !== '.') { yield { @@ -2003,61 +2003,61 @@ export namespace DHTRequest { } } - while (reader.pos < end) { - const tag = reader.uint32() + while (r.pos < end) { + const tag = r.uint32() switch (tag >>> 3) { case 1: { yield { field: `${prefix}type`, - value: DHTRequest.Type.codec().decode(reader) + value: DHTRequest.Type.codec().decode(r) } break } case 2: { yield { field: `${prefix}peer`, - value: reader.bytes() + value: r.bytes() } break } case 3: { yield { field: `${prefix}cid`, - value: reader.bytes() + value: r.bytes() } break } case 4: { yield { field: `${prefix}key`, - value: reader.bytes() + value: r.bytes() } break } case 5: { yield { field: `${prefix}value`, - value: reader.bytes() + value: r.bytes() } break } case 6: { yield { field: `${prefix}count`, - value: reader.int32() + value: r.int32() } break } case 7: { yield { field: `${prefix}timeout`, - value: reader.int64() + value: r.int64() } break } default: { - reader.skipType(tag & 7) + r.skipType(tag & 7) break } } @@ -2176,41 +2176,41 @@ export namespace DHTResponse { if (opts.lengthDelimited !== false) { w.ldelim() } - }, (reader, length, opts = {}) => { + }, (r, length, opts = {}) => { const obj: any = { type: Type.BEGIN } - const end = length == null ? reader.len : reader.pos + length + const end = length == null ? r.len : r.pos + length - while (reader.pos < end) { - const tag = reader.uint32() + while (r.pos < end) { + const tag = r.uint32() switch (tag >>> 3) { case 1: { - obj.type = DHTResponse.Type.codec().decode(reader) + obj.type = DHTResponse.Type.codec().decode(r) break } case 2: { - obj.peer = PeerInfo.codec().decode(reader, reader.uint32(), { + obj.peer = PeerInfo.codec().decode(r, r.uint32(), { limits: opts.limits?.peer }) break } case 3: { - obj.value = reader.bytes() + obj.value = r.bytes() break } default: { - reader.skipType(tag & 7) + r.skipType(tag & 7) break } } } return obj - }, function * (reader, length, prefix, opts = {}) { - const end = length == null ? reader.len : reader.pos + length + }, function * (r, length, prefix, opts = {}) { + const end = length == null ? r.len : r.pos + length if (prefix !== '.') { yield { @@ -2220,19 +2220,19 @@ export namespace DHTResponse { } } - while (reader.pos < end) { - const tag = reader.uint32() + while (r.pos < end) { + const tag = r.uint32() switch (tag >>> 3) { case 1: { yield { field: `${prefix}type`, - value: DHTResponse.Type.codec().decode(reader) + value: DHTResponse.Type.codec().decode(r) } break } case 2: { - yield * PeerInfo.codec().stream(reader, reader.uint32(), `${prefix}peer.`, { + yield * PeerInfo.codec().stream(r, r.uint32(), `${prefix}peer.`, { limits: opts.limits?.peer }) @@ -2241,12 +2241,12 @@ export namespace DHTResponse { case 3: { yield { field: `${prefix}value`, - value: reader.bytes() + value: r.bytes() } break } default: { - reader.skipType(tag & 7) + r.skipType(tag & 7) break } } @@ -2339,20 +2339,20 @@ export namespace PeerInfo { if (opts.lengthDelimited !== false) { w.ldelim() } - }, (reader, length, opts = {}) => { + }, (r, length, opts = {}) => { const obj: any = { id: uint8ArrayAlloc(0), addrs: [] } - const end = length == null ? reader.len : reader.pos + length + const end = length == null ? r.len : r.pos + length - while (reader.pos < end) { - const tag = reader.uint32() + while (r.pos < end) { + const tag = r.uint32() switch (tag >>> 3) { case 1: { - obj.id = reader.bytes() + obj.id = r.bytes() break } case 2: { @@ -2360,23 +2360,23 @@ export namespace PeerInfo { throw new MaxLengthError('Decode error - repeated field "addrs" had too many elements') } - obj.addrs.push(reader.bytes()) + obj.addrs.push(r.bytes()) break } default: { - reader.skipType(tag & 7) + r.skipType(tag & 7) break } } } return obj - }, function * (reader, length, prefix, opts = {}) { + }, function * (r, length, prefix, opts = {}) { const obj = { addrs: 0 } - const end = length == null ? reader.len : reader.pos + length + const end = length == null ? r.len : r.pos + length if (prefix !== '.') { yield { @@ -2386,14 +2386,14 @@ export namespace PeerInfo { } } - while (reader.pos < end) { - const tag = reader.uint32() + while (r.pos < end) { + const tag = r.uint32() switch (tag >>> 3) { case 1: { yield { field: `${prefix}id`, - value: reader.bytes() + value: r.bytes() } break } @@ -2405,7 +2405,7 @@ export namespace PeerInfo { yield { field: `${prefix}addrs[]`, index: obj.addrs, - value: reader.bytes() + value: r.bytes() } obj.addrs++ @@ -2413,7 +2413,7 @@ export namespace PeerInfo { break } default: { - reader.skipType(tag & 7) + r.skipType(tag & 7) break } } @@ -2514,43 +2514,43 @@ export namespace ConnManagerRequest { if (opts.lengthDelimited !== false) { w.ldelim() } - }, (reader, length, opts = {}) => { + }, (r, length, opts = {}) => { const obj: any = { type: Type.TAG_PEER } - const end = length == null ? reader.len : reader.pos + length + const end = length == null ? r.len : r.pos + length - while (reader.pos < end) { - const tag = reader.uint32() + while (r.pos < end) { + const tag = r.uint32() switch (tag >>> 3) { case 1: { - obj.type = ConnManagerRequest.Type.codec().decode(reader) + obj.type = ConnManagerRequest.Type.codec().decode(r) break } case 2: { - obj.peer = reader.bytes() + obj.peer = r.bytes() break } case 3: { - obj.tag = reader.string() + obj.tag = r.string() break } case 4: { - obj.weight = reader.int64() + obj.weight = r.int64() break } default: { - reader.skipType(tag & 7) + r.skipType(tag & 7) break } } } return obj - }, function * (reader, length, prefix, opts = {}) { - const end = length == null ? reader.len : reader.pos + length + }, function * (r, length, prefix, opts = {}) { + const end = length == null ? r.len : r.pos + length if (prefix !== '.') { yield { @@ -2560,40 +2560,40 @@ export namespace ConnManagerRequest { } } - while (reader.pos < end) { - const tag = reader.uint32() + while (r.pos < end) { + const tag = r.uint32() switch (tag >>> 3) { case 1: { yield { field: `${prefix}type`, - value: ConnManagerRequest.Type.codec().decode(reader) + value: ConnManagerRequest.Type.codec().decode(r) } break } case 2: { yield { field: `${prefix}peer`, - value: reader.bytes() + value: r.bytes() } break } case 3: { yield { field: `${prefix}tag`, - value: reader.string() + value: r.string() } break } case 4: { yield { field: `${prefix}weight`, - value: reader.int64() + value: r.int64() } break } default: { - reader.skipType(tag & 7) + r.skipType(tag & 7) break } } @@ -2667,31 +2667,31 @@ export namespace DisconnectRequest { if (opts.lengthDelimited !== false) { w.ldelim() } - }, (reader, length, opts = {}) => { + }, (r, length, opts = {}) => { const obj: any = { peer: uint8ArrayAlloc(0) } - const end = length == null ? reader.len : reader.pos + length + const end = length == null ? r.len : r.pos + length - while (reader.pos < end) { - const tag = reader.uint32() + while (r.pos < end) { + const tag = r.uint32() switch (tag >>> 3) { case 1: { - obj.peer = reader.bytes() + obj.peer = r.bytes() break } default: { - reader.skipType(tag & 7) + r.skipType(tag & 7) break } } } return obj - }, function * (reader, length, prefix, opts = {}) { - const end = length == null ? reader.len : reader.pos + length + }, function * (r, length, prefix, opts = {}) { + const end = length == null ? r.len : r.pos + length if (prefix !== '.') { yield { @@ -2701,19 +2701,19 @@ export namespace DisconnectRequest { } } - while (reader.pos < end) { - const tag = reader.uint32() + while (r.pos < end) { + const tag = r.uint32() switch (tag >>> 3) { case 1: { yield { field: `${prefix}peer`, - value: reader.bytes() + value: r.bytes() } break } default: { - reader.skipType(tag & 7) + r.skipType(tag & 7) break } } @@ -2804,39 +2804,39 @@ export namespace PSRequest { if (opts.lengthDelimited !== false) { w.ldelim() } - }, (reader, length, opts = {}) => { + }, (r, length, opts = {}) => { const obj: any = { type: Type.GET_TOPICS } - const end = length == null ? reader.len : reader.pos + length + const end = length == null ? r.len : r.pos + length - while (reader.pos < end) { - const tag = reader.uint32() + while (r.pos < end) { + const tag = r.uint32() switch (tag >>> 3) { case 1: { - obj.type = PSRequest.Type.codec().decode(reader) + obj.type = PSRequest.Type.codec().decode(r) break } case 2: { - obj.topic = reader.string() + obj.topic = r.string() break } case 3: { - obj.data = reader.bytes() + obj.data = r.bytes() break } default: { - reader.skipType(tag & 7) + r.skipType(tag & 7) break } } } return obj - }, function * (reader, length, prefix, opts = {}) { - const end = length == null ? reader.len : reader.pos + length + }, function * (r, length, prefix, opts = {}) { + const end = length == null ? r.len : r.pos + length if (prefix !== '.') { yield { @@ -2846,33 +2846,33 @@ export namespace PSRequest { } } - while (reader.pos < end) { - const tag = reader.uint32() + while (r.pos < end) { + const tag = r.uint32() switch (tag >>> 3) { case 1: { yield { field: `${prefix}type`, - value: PSRequest.Type.codec().decode(reader) + value: PSRequest.Type.codec().decode(r) } break } case 2: { yield { field: `${prefix}topic`, - value: reader.string() + value: r.string() } break } case 3: { yield { field: `${prefix}data`, - value: reader.bytes() + value: r.bytes() } break } default: { - reader.skipType(tag & 7) + r.skipType(tag & 7) break } } @@ -2973,27 +2973,27 @@ export namespace PSMessage { if (opts.lengthDelimited !== false) { w.ldelim() } - }, (reader, length, opts = {}) => { + }, (r, length, opts = {}) => { const obj: any = { topicIDs: [] } - const end = length == null ? reader.len : reader.pos + length + const end = length == null ? r.len : r.pos + length - while (reader.pos < end) { - const tag = reader.uint32() + while (r.pos < end) { + const tag = r.uint32() switch (tag >>> 3) { case 1: { - obj.from = reader.bytes() + obj.from = r.bytes() break } case 2: { - obj.data = reader.bytes() + obj.data = r.bytes() break } case 3: { - obj.seqno = reader.bytes() + obj.seqno = r.bytes() break } case 4: { @@ -3001,31 +3001,31 @@ export namespace PSMessage { throw new MaxLengthError('Decode error - repeated field "topicIDs" had too many elements') } - obj.topicIDs.push(reader.string()) + obj.topicIDs.push(r.string()) break } case 5: { - obj.signature = reader.bytes() + obj.signature = r.bytes() break } case 6: { - obj.key = reader.bytes() + obj.key = r.bytes() break } default: { - reader.skipType(tag & 7) + r.skipType(tag & 7) break } } } return obj - }, function * (reader, length, prefix, opts = {}) { + }, function * (r, length, prefix, opts = {}) { const obj = { topicIDs: 0 } - const end = length == null ? reader.len : reader.pos + length + const end = length == null ? r.len : r.pos + length if (prefix !== '.') { yield { @@ -3035,28 +3035,28 @@ export namespace PSMessage { } } - while (reader.pos < end) { - const tag = reader.uint32() + while (r.pos < end) { + const tag = r.uint32() switch (tag >>> 3) { case 1: { yield { field: `${prefix}from`, - value: reader.bytes() + value: r.bytes() } break } case 2: { yield { field: `${prefix}data`, - value: reader.bytes() + value: r.bytes() } break } case 3: { yield { field: `${prefix}seqno`, - value: reader.bytes() + value: r.bytes() } break } @@ -3068,7 +3068,7 @@ export namespace PSMessage { yield { field: `${prefix}topicIDs[]`, index: obj.topicIDs, - value: reader.string() + value: r.string() } obj.topicIDs++ @@ -3078,19 +3078,19 @@ export namespace PSMessage { case 5: { yield { field: `${prefix}signature`, - value: reader.bytes() + value: r.bytes() } break } case 6: { yield { field: `${prefix}key`, - value: reader.bytes() + value: r.bytes() } break } default: { - reader.skipType(tag & 7) + r.skipType(tag & 7) break } } @@ -3185,16 +3185,16 @@ export namespace PSResponse { if (opts.lengthDelimited !== false) { w.ldelim() } - }, (reader, length, opts = {}) => { + }, (r, length, opts = {}) => { const obj: any = { topics: [], peerIDs: [] } - const end = length == null ? reader.len : reader.pos + length + const end = length == null ? r.len : r.pos + length - while (reader.pos < end) { - const tag = reader.uint32() + while (r.pos < end) { + const tag = r.uint32() switch (tag >>> 3) { case 1: { @@ -3202,7 +3202,7 @@ export namespace PSResponse { throw new MaxLengthError('Decode error - repeated field "topics" had too many elements') } - obj.topics.push(reader.string()) + obj.topics.push(r.string()) break } case 2: { @@ -3210,24 +3210,24 @@ export namespace PSResponse { throw new MaxLengthError('Decode error - repeated field "peerIDs" had too many elements') } - obj.peerIDs.push(reader.bytes()) + obj.peerIDs.push(r.bytes()) break } default: { - reader.skipType(tag & 7) + r.skipType(tag & 7) break } } } return obj - }, function * (reader, length, prefix, opts = {}) { + }, function * (r, length, prefix, opts = {}) { const obj = { topics: 0, peerIDs: 0 } - const end = length == null ? reader.len : reader.pos + length + const end = length == null ? r.len : r.pos + length if (prefix !== '.') { yield { @@ -3237,8 +3237,8 @@ export namespace PSResponse { } } - while (reader.pos < end) { - const tag = reader.uint32() + while (r.pos < end) { + const tag = r.uint32() switch (tag >>> 3) { case 1: { @@ -3249,7 +3249,7 @@ export namespace PSResponse { yield { field: `${prefix}topics[]`, index: obj.topics, - value: reader.string() + value: r.string() } obj.topics++ @@ -3264,7 +3264,7 @@ export namespace PSResponse { yield { field: `${prefix}peerIDs[]`, index: obj.peerIDs, - value: reader.bytes() + value: r.bytes() } obj.peerIDs++ @@ -3272,7 +3272,7 @@ export namespace PSResponse { break } default: { - reader.skipType(tag & 7) + r.skipType(tag & 7) break } } @@ -3370,24 +3370,24 @@ export namespace PeerstoreRequest { if (opts.lengthDelimited !== false) { w.ldelim() } - }, (reader, length, opts = {}) => { + }, (r, length, opts = {}) => { const obj: any = { type: Type.INVALID, protos: [] } - const end = length == null ? reader.len : reader.pos + length + const end = length == null ? r.len : r.pos + length - while (reader.pos < end) { - const tag = reader.uint32() + while (r.pos < end) { + const tag = r.uint32() switch (tag >>> 3) { case 1: { - obj.type = PeerstoreRequest.Type.codec().decode(reader) + obj.type = PeerstoreRequest.Type.codec().decode(r) break } case 2: { - obj.id = reader.bytes() + obj.id = r.bytes() break } case 3: { @@ -3395,23 +3395,23 @@ export namespace PeerstoreRequest { throw new MaxLengthError('Decode error - repeated field "protos" had too many elements') } - obj.protos.push(reader.string()) + obj.protos.push(r.string()) break } default: { - reader.skipType(tag & 7) + r.skipType(tag & 7) break } } } return obj - }, function * (reader, length, prefix, opts = {}) { + }, function * (r, length, prefix, opts = {}) { const obj = { protos: 0 } - const end = length == null ? reader.len : reader.pos + length + const end = length == null ? r.len : r.pos + length if (prefix !== '.') { yield { @@ -3421,21 +3421,21 @@ export namespace PeerstoreRequest { } } - while (reader.pos < end) { - const tag = reader.uint32() + while (r.pos < end) { + const tag = r.uint32() switch (tag >>> 3) { case 1: { yield { field: `${prefix}type`, - value: PeerstoreRequest.Type.codec().decode(reader) + value: PeerstoreRequest.Type.codec().decode(r) } break } case 2: { yield { field: `${prefix}id`, - value: reader.bytes() + value: r.bytes() } break } @@ -3447,7 +3447,7 @@ export namespace PeerstoreRequest { yield { field: `${prefix}protos[]`, index: obj.protos, - value: reader.string() + value: r.string() } obj.protos++ @@ -3455,7 +3455,7 @@ export namespace PeerstoreRequest { break } default: { - reader.skipType(tag & 7) + r.skipType(tag & 7) break } } @@ -3533,19 +3533,19 @@ export namespace PeerstoreResponse { if (opts.lengthDelimited !== false) { w.ldelim() } - }, (reader, length, opts = {}) => { + }, (r, length, opts = {}) => { const obj: any = { protos: [] } - const end = length == null ? reader.len : reader.pos + length + const end = length == null ? r.len : r.pos + length - while (reader.pos < end) { - const tag = reader.uint32() + while (r.pos < end) { + const tag = r.uint32() switch (tag >>> 3) { case 1: { - obj.peer = PeerInfo.codec().decode(reader, reader.uint32(), { + obj.peer = PeerInfo.codec().decode(r, r.uint32(), { limits: opts.limits?.peer }) break @@ -3555,23 +3555,23 @@ export namespace PeerstoreResponse { throw new MaxLengthError('Decode error - repeated field "protos" had too many elements') } - obj.protos.push(reader.string()) + obj.protos.push(r.string()) break } default: { - reader.skipType(tag & 7) + r.skipType(tag & 7) break } } } return obj - }, function * (reader, length, prefix, opts = {}) { + }, function * (r, length, prefix, opts = {}) { const obj = { protos: 0 } - const end = length == null ? reader.len : reader.pos + length + const end = length == null ? r.len : r.pos + length if (prefix !== '.') { yield { @@ -3581,12 +3581,12 @@ export namespace PeerstoreResponse { } } - while (reader.pos < end) { - const tag = reader.uint32() + while (r.pos < end) { + const tag = r.uint32() switch (tag >>> 3) { case 1: { - yield * PeerInfo.codec().stream(reader, reader.uint32(), `${prefix}peer.`, { + yield * PeerInfo.codec().stream(r, r.uint32(), `${prefix}peer.`, { limits: opts.limits?.peer }) @@ -3600,7 +3600,7 @@ export namespace PeerstoreResponse { yield { field: `${prefix}protos[]`, index: obj.protos, - value: reader.string() + value: r.string() } obj.protos++ @@ -3608,7 +3608,7 @@ export namespace PeerstoreResponse { break } default: { - reader.skipType(tag & 7) + r.skipType(tag & 7) break } } diff --git a/packages/protons/test/fixtures/dht.ts b/packages/protons/test/fixtures/dht.ts index a7626f8..49e96a2 100644 --- a/packages/protons/test/fixtures/dht.ts +++ b/packages/protons/test/fixtures/dht.ts @@ -48,45 +48,45 @@ export namespace Record { if (opts.lengthDelimited !== false) { w.ldelim() } - }, (reader, length, opts = {}) => { + }, (r, length, opts = {}) => { const obj: any = {} - const end = length == null ? reader.len : reader.pos + length + const end = length == null ? r.len : r.pos + length - while (reader.pos < end) { - const tag = reader.uint32() + while (r.pos < end) { + const tag = r.uint32() switch (tag >>> 3) { case 1: { - obj.key = reader.bytes() + obj.key = r.bytes() break } case 2: { - obj.value = reader.bytes() + obj.value = r.bytes() break } case 3: { - obj.author = reader.bytes() + obj.author = r.bytes() break } case 4: { - obj.signature = reader.bytes() + obj.signature = r.bytes() break } case 5: { - obj.timeReceived = reader.string() + obj.timeReceived = r.string() break } default: { - reader.skipType(tag & 7) + r.skipType(tag & 7) break } } } return obj - }, function * (reader, length, prefix, opts = {}) { - const end = length == null ? reader.len : reader.pos + length + }, function * (r, length, prefix, opts = {}) { + const end = length == null ? r.len : r.pos + length if (prefix !== '.') { yield { @@ -96,47 +96,47 @@ export namespace Record { } } - while (reader.pos < end) { - const tag = reader.uint32() + while (r.pos < end) { + const tag = r.uint32() switch (tag >>> 3) { case 1: { yield { field: `${prefix}key`, - value: reader.bytes() + value: r.bytes() } break } case 2: { yield { field: `${prefix}value`, - value: reader.bytes() + value: r.bytes() } break } case 3: { yield { field: `${prefix}author`, - value: reader.bytes() + value: r.bytes() } break } case 4: { yield { field: `${prefix}signature`, - value: reader.bytes() + value: r.bytes() } break } case 5: { yield { field: `${prefix}timeReceived`, - value: reader.string() + value: r.string() } break } default: { - reader.skipType(tag & 7) + r.skipType(tag & 7) break } } @@ -283,19 +283,19 @@ export namespace Message { if (opts.lengthDelimited !== false) { w.ldelim() } - }, (reader, length, opts = {}) => { + }, (r, length, opts = {}) => { const obj: any = { addrs: [] } - const end = length == null ? reader.len : reader.pos + length + const end = length == null ? r.len : r.pos + length - while (reader.pos < end) { - const tag = reader.uint32() + while (r.pos < end) { + const tag = r.uint32() switch (tag >>> 3) { case 1: { - obj.id = reader.bytes() + obj.id = r.bytes() break } case 2: { @@ -303,27 +303,27 @@ export namespace Message { throw new MaxLengthError('Decode error - repeated field "addrs" had too many elements') } - obj.addrs.push(reader.bytes()) + obj.addrs.push(r.bytes()) break } case 3: { - obj.connection = Message.ConnectionType.codec().decode(reader) + obj.connection = Message.ConnectionType.codec().decode(r) break } default: { - reader.skipType(tag & 7) + r.skipType(tag & 7) break } } } return obj - }, function * (reader, length, prefix, opts = {}) { + }, function * (r, length, prefix, opts = {}) { const obj = { addrs: 0 } - const end = length == null ? reader.len : reader.pos + length + const end = length == null ? r.len : r.pos + length if (prefix !== '.') { yield { @@ -333,14 +333,14 @@ export namespace Message { } } - while (reader.pos < end) { - const tag = reader.uint32() + while (r.pos < end) { + const tag = r.uint32() switch (tag >>> 3) { case 1: { yield { field: `${prefix}id`, - value: reader.bytes() + value: r.bytes() } break } @@ -352,7 +352,7 @@ export namespace Message { yield { field: `${prefix}addrs[]`, index: obj.addrs, - value: reader.bytes() + value: r.bytes() } obj.addrs++ @@ -362,12 +362,12 @@ export namespace Message { case 3: { yield { field: `${prefix}connection`, - value: Message.ConnectionType.codec().decode(reader) + value: Message.ConnectionType.codec().decode(r) } break } default: { - reader.skipType(tag & 7) + r.skipType(tag & 7) break } } @@ -461,32 +461,32 @@ export namespace Message { if (opts.lengthDelimited !== false) { w.ldelim() } - }, (reader, length, opts = {}) => { + }, (r, length, opts = {}) => { const obj: any = { closerPeers: [], providerPeers: [] } - const end = length == null ? reader.len : reader.pos + length + const end = length == null ? r.len : r.pos + length - while (reader.pos < end) { - const tag = reader.uint32() + while (r.pos < end) { + const tag = r.uint32() switch (tag >>> 3) { case 1: { - obj.type = Message.MessageType.codec().decode(reader) + obj.type = Message.MessageType.codec().decode(r) break } case 10: { - obj.clusterLevelRaw = reader.int32() + obj.clusterLevelRaw = r.int32() break } case 2: { - obj.key = reader.bytes() + obj.key = r.bytes() break } case 3: { - obj.record = reader.bytes() + obj.record = r.bytes() break } case 8: { @@ -494,7 +494,7 @@ export namespace Message { throw new MaxLengthError('Decode error - repeated field "closerPeers" had too many elements') } - obj.closerPeers.push(Message.Peer.codec().decode(reader, reader.uint32(), { + obj.closerPeers.push(Message.Peer.codec().decode(r, r.uint32(), { limits: opts.limits?.closerPeers$ })) break @@ -504,26 +504,26 @@ export namespace Message { throw new MaxLengthError('Decode error - repeated field "providerPeers" had too many elements') } - obj.providerPeers.push(Message.Peer.codec().decode(reader, reader.uint32(), { + obj.providerPeers.push(Message.Peer.codec().decode(r, r.uint32(), { limits: opts.limits?.providerPeers$ })) break } default: { - reader.skipType(tag & 7) + r.skipType(tag & 7) break } } } return obj - }, function * (reader, length, prefix, opts = {}) { + }, function * (r, length, prefix, opts = {}) { const obj = { closerPeers: 0, providerPeers: 0 } - const end = length == null ? reader.len : reader.pos + length + const end = length == null ? r.len : r.pos + length if (prefix !== '.') { yield { @@ -533,35 +533,35 @@ export namespace Message { } } - while (reader.pos < end) { - const tag = reader.uint32() + while (r.pos < end) { + const tag = r.uint32() switch (tag >>> 3) { case 1: { yield { field: `${prefix}type`, - value: Message.MessageType.codec().decode(reader) + value: Message.MessageType.codec().decode(r) } break } case 10: { yield { field: `${prefix}clusterLevelRaw`, - value: reader.int32() + value: r.int32() } break } case 2: { yield { field: `${prefix}key`, - value: reader.bytes() + value: r.bytes() } break } case 3: { yield { field: `${prefix}record`, - value: reader.bytes() + value: r.bytes() } break } @@ -570,7 +570,7 @@ export namespace Message { throw new MaxLengthError('Streaming decode error - repeated field "closerPeers" had too many elements') } - for (const evt of Message.Peer.codec().stream(reader, reader.uint32(), `${prefix}closerPeers[].`, { + for (const evt of Message.Peer.codec().stream(r, r.uint32(), `${prefix}closerPeers[].`, { limits: opts.limits?.closerPeers$ })) { yield { @@ -588,7 +588,7 @@ export namespace Message { throw new MaxLengthError('Streaming decode error - repeated field "providerPeers" had too many elements') } - for (const evt of Message.Peer.codec().stream(reader, reader.uint32(), `${prefix}providerPeers[].`, { + for (const evt of Message.Peer.codec().stream(r, r.uint32(), `${prefix}providerPeers[].`, { limits: opts.limits?.providerPeers$ })) { yield { @@ -602,7 +602,7 @@ export namespace Message { break } default: { - reader.skipType(tag & 7) + r.skipType(tag & 7) break } } diff --git a/packages/protons/test/fixtures/maps.ts b/packages/protons/test/fixtures/maps.ts index f939e48..fc192f4 100644 --- a/packages/protons/test/fixtures/maps.ts +++ b/packages/protons/test/fixtures/maps.ts @@ -1,4 +1,4 @@ -import { decodeMessage, encodeMessage, enumeration, MaxLengthError, MaxSizeError, message, streamMessage } from 'protons-runtime' +import { decodeMessage, encodeMessage, enumeration, MaxLengthError, MaxSizeError, message, reader, streamMessage } from 'protons-runtime' import type { Codec, DecodeOptions } from 'protons-runtime' import type { Uint8ArrayList } from 'uint8arraylist' @@ -41,53 +41,63 @@ export namespace SubMessage { } if (obj.bar != null && obj.bar.length > 0) { + w.uint32(18) + w.fork() + for (const value of obj.bar) { - w.uint32(16) w.uint32(value) } + + w.ldelim() } if (opts.lengthDelimited !== false) { w.ldelim() } - }, (reader, length, opts = {}) => { + }, (r, length, opts = {}) => { const obj: any = { foo: '', bar: [] } - const end = length == null ? reader.len : reader.pos + length + const end = length == null ? r.len : r.pos + length - while (reader.pos < end) { - const tag = reader.uint32() + while (r.pos < end) { + const tag = r.uint32() switch (tag >>> 3) { case 1: { - obj.foo = reader.string() + obj.foo = r.string() break } case 2: { - if (opts.limits?.bar != null && obj.bar.length === opts.limits.bar) { - throw new MaxLengthError('Decode error - repeated field "bar" had too many elements') + const b = r.bytes() + const r2 = reader(b) + + while (r2.pos < r2.len) { + if (opts.limits?.bar != null && obj.bar.length === opts.limits.bar) { + throw new MaxLengthError('Decode error - repeated field "bar" had too many elements') + } + + obj.bar.push(r2.uint32()) } - obj.bar.push(reader.uint32()) break } default: { - reader.skipType(tag & 7) + r.skipType(tag & 7) break } } } return obj - }, function * (reader, length, prefix, opts = {}) { + }, function * (r, length, prefix, opts = {}) { const obj = { bar: 0 } - const end = length == null ? reader.len : reader.pos + length + const end = length == null ? r.len : r.pos + length if (prefix !== '.') { yield { @@ -97,34 +107,39 @@ export namespace SubMessage { } } - while (reader.pos < end) { - const tag = reader.uint32() + while (r.pos < end) { + const tag = r.uint32() switch (tag >>> 3) { case 1: { yield { field: `${prefix}foo`, - value: reader.string() + value: r.string() } break } case 2: { - if (opts.limits?.bar != null && obj.bar === opts.limits.bar) { - throw new MaxLengthError('Streaming decode error - repeated field "bar" had too many elements') - } + const b = r.bytes() + const r2 = reader(b) - yield { - field: `${prefix}bar[]`, - index: obj.bar, - value: reader.uint32() - } + while (r2.pos < r2.len) { + if (opts.limits?.bar != null && obj.bar === opts.limits.bar) { + throw new MaxLengthError('Streaming decode error - repeated field "bar" had too many elements') + } - obj.bar++ + yield { + field: `${prefix}bar[]`, + index: obj.bar, + value: r2.uint32() + } + + obj.bar++ + } break } default: { - reader.skipType(tag & 7) + r.skipType(tag & 7) break } } @@ -204,36 +219,36 @@ export namespace MapTypes { if (opts.lengthDelimited !== false) { w.ldelim() } - }, (reader, length, opts = {}) => { + }, (r, length, opts = {}) => { const obj: any = { key: '', value: '' } - const end = length == null ? reader.len : reader.pos + length + const end = length == null ? r.len : r.pos + length - while (reader.pos < end) { - const tag = reader.uint32() + while (r.pos < end) { + const tag = r.uint32() switch (tag >>> 3) { case 1: { - obj.key = reader.string() + obj.key = r.string() break } case 2: { - obj.value = reader.string() + obj.value = r.string() break } default: { - reader.skipType(tag & 7) + r.skipType(tag & 7) break } } } return obj - }, function * (reader, length, prefix, opts = {}) { - const end = length == null ? reader.len : reader.pos + length + }, function * (r, length, prefix, opts = {}) { + const end = length == null ? r.len : r.pos + length if (prefix !== '.') { yield { @@ -243,26 +258,26 @@ export namespace MapTypes { } } - while (reader.pos < end) { - const tag = reader.uint32() + while (r.pos < end) { + const tag = r.uint32() switch (tag >>> 3) { case 1: { yield { field: `${prefix}key`, - value: reader.string() + value: r.string() } break } case 2: { yield { field: `${prefix}value`, - value: reader.string() + value: r.string() } break } default: { - reader.skipType(tag & 7) + r.skipType(tag & 7) break } } @@ -332,36 +347,36 @@ export namespace MapTypes { if (opts.lengthDelimited !== false) { w.ldelim() } - }, (reader, length, opts = {}) => { + }, (r, length, opts = {}) => { const obj: any = { key: 0, value: 0 } - const end = length == null ? reader.len : reader.pos + length + const end = length == null ? r.len : r.pos + length - while (reader.pos < end) { - const tag = reader.uint32() + while (r.pos < end) { + const tag = r.uint32() switch (tag >>> 3) { case 1: { - obj.key = reader.int32() + obj.key = r.int32() break } case 2: { - obj.value = reader.int32() + obj.value = r.int32() break } default: { - reader.skipType(tag & 7) + r.skipType(tag & 7) break } } } return obj - }, function * (reader, length, prefix, opts = {}) { - const end = length == null ? reader.len : reader.pos + length + }, function * (r, length, prefix, opts = {}) { + const end = length == null ? r.len : r.pos + length if (prefix !== '.') { yield { @@ -371,26 +386,26 @@ export namespace MapTypes { } } - while (reader.pos < end) { - const tag = reader.uint32() + while (r.pos < end) { + const tag = r.uint32() switch (tag >>> 3) { case 1: { yield { field: `${prefix}key`, - value: reader.int32() + value: r.int32() } break } case 2: { yield { field: `${prefix}value`, - value: reader.int32() + value: r.int32() } break } default: { - reader.skipType(tag & 7) + r.skipType(tag & 7) break } } @@ -460,36 +475,36 @@ export namespace MapTypes { if (opts.lengthDelimited !== false) { w.ldelim() } - }, (reader, length, opts = {}) => { + }, (r, length, opts = {}) => { const obj: any = { key: false, value: false } - const end = length == null ? reader.len : reader.pos + length + const end = length == null ? r.len : r.pos + length - while (reader.pos < end) { - const tag = reader.uint32() + while (r.pos < end) { + const tag = r.uint32() switch (tag >>> 3) { case 1: { - obj.key = reader.bool() + obj.key = r.bool() break } case 2: { - obj.value = reader.bool() + obj.value = r.bool() break } default: { - reader.skipType(tag & 7) + r.skipType(tag & 7) break } } } return obj - }, function * (reader, length, prefix, opts = {}) { - const end = length == null ? reader.len : reader.pos + length + }, function * (r, length, prefix, opts = {}) { + const end = length == null ? r.len : r.pos + length if (prefix !== '.') { yield { @@ -499,26 +514,26 @@ export namespace MapTypes { } } - while (reader.pos < end) { - const tag = reader.uint32() + while (r.pos < end) { + const tag = r.uint32() switch (tag >>> 3) { case 1: { yield { field: `${prefix}key`, - value: reader.bool() + value: r.bool() } break } case 2: { yield { field: `${prefix}value`, - value: reader.bool() + value: r.bool() } break } default: { - reader.skipType(tag & 7) + r.skipType(tag & 7) break } } @@ -588,37 +603,37 @@ export namespace MapTypes { if (opts.lengthDelimited !== false) { w.ldelim() } - }, (reader, length, opts = {}) => { + }, (r, length, opts = {}) => { const obj: any = { key: '' } - const end = length == null ? reader.len : reader.pos + length + const end = length == null ? r.len : r.pos + length - while (reader.pos < end) { - const tag = reader.uint32() + while (r.pos < end) { + const tag = r.uint32() switch (tag >>> 3) { case 1: { - obj.key = reader.string() + obj.key = r.string() break } case 2: { - obj.value = SubMessage.codec().decode(reader, reader.uint32(), { + obj.value = SubMessage.codec().decode(r, r.uint32(), { limits: opts.limits?.value }) break } default: { - reader.skipType(tag & 7) + r.skipType(tag & 7) break } } } return obj - }, function * (reader, length, prefix, opts = {}) { - const end = length == null ? reader.len : reader.pos + length + }, function * (r, length, prefix, opts = {}) { + const end = length == null ? r.len : r.pos + length if (prefix !== '.') { yield { @@ -628,26 +643,26 @@ export namespace MapTypes { } } - while (reader.pos < end) { - const tag = reader.uint32() + while (r.pos < end) { + const tag = r.uint32() switch (tag >>> 3) { case 1: { yield { field: `${prefix}key`, - value: reader.string() + value: r.string() } break } case 2: { - yield * SubMessage.codec().stream(reader, reader.uint32(), `${prefix}value.`, { + yield * SubMessage.codec().stream(r, r.uint32(), `${prefix}value.`, { limits: opts.limits?.value }) break } default: { - reader.skipType(tag & 7) + r.skipType(tag & 7) break } } @@ -733,36 +748,36 @@ export namespace MapTypes { if (opts.lengthDelimited !== false) { w.ldelim() } - }, (reader, length, opts = {}) => { + }, (r, length, opts = {}) => { const obj: any = { key: '', value: EnumValue.NO_VALUE } - const end = length == null ? reader.len : reader.pos + length + const end = length == null ? r.len : r.pos + length - while (reader.pos < end) { - const tag = reader.uint32() + while (r.pos < end) { + const tag = r.uint32() switch (tag >>> 3) { case 1: { - obj.key = reader.string() + obj.key = r.string() break } case 2: { - obj.value = EnumValue.codec().decode(reader) + obj.value = EnumValue.codec().decode(r) break } default: { - reader.skipType(tag & 7) + r.skipType(tag & 7) break } } } return obj - }, function * (reader, length, prefix, opts = {}) { - const end = length == null ? reader.len : reader.pos + length + }, function * (r, length, prefix, opts = {}) { + const end = length == null ? r.len : r.pos + length if (prefix !== '.') { yield { @@ -772,26 +787,26 @@ export namespace MapTypes { } } - while (reader.pos < end) { - const tag = reader.uint32() + while (r.pos < end) { + const tag = r.uint32() switch (tag >>> 3) { case 1: { yield { field: `${prefix}key`, - value: reader.string() + value: r.string() } break } case 2: { yield { field: `${prefix}value`, - value: EnumValue.codec().decode(reader) + value: EnumValue.codec().decode(r) } break } default: { - reader.skipType(tag & 7) + r.skipType(tag & 7) break } } @@ -880,7 +895,7 @@ export namespace MapTypes { if (opts.lengthDelimited !== false) { w.ldelim() } - }, (reader, length, opts = {}) => { + }, (r, length, opts = {}) => { const obj: any = { stringMap: new Map(), intMap: new Map(), @@ -889,10 +904,10 @@ export namespace MapTypes { enumMap: new Map() } - const end = length == null ? reader.len : reader.pos + length + const end = length == null ? r.len : r.pos + length - while (reader.pos < end) { - const tag = reader.uint32() + while (r.pos < end) { + const tag = r.uint32() switch (tag >>> 3) { case 1: { @@ -900,7 +915,7 @@ export namespace MapTypes { throw new MaxSizeError('Decode error - map field "stringMap" had too many elements') } - const entry = MapTypes.MapTypes$stringMapEntry.codec().decode(reader, reader.uint32(), { + const entry = MapTypes.MapTypes$stringMapEntry.codec().decode(r, r.uint32(), { limits: { value: opts.limits?.stringMap$value } @@ -913,7 +928,7 @@ export namespace MapTypes { throw new MaxSizeError('Decode error - map field "intMap" had too many elements') } - const entry = MapTypes.MapTypes$intMapEntry.codec().decode(reader, reader.uint32(), { + const entry = MapTypes.MapTypes$intMapEntry.codec().decode(r, r.uint32(), { limits: { value: opts.limits?.intMap$value } @@ -926,7 +941,7 @@ export namespace MapTypes { throw new MaxSizeError('Decode error - map field "boolMap" had too many elements') } - const entry = MapTypes.MapTypes$boolMapEntry.codec().decode(reader, reader.uint32(), { + const entry = MapTypes.MapTypes$boolMapEntry.codec().decode(r, r.uint32(), { limits: { value: opts.limits?.boolMap$value } @@ -939,7 +954,7 @@ export namespace MapTypes { throw new MaxSizeError('Decode error - map field "messageMap" had too many elements') } - const entry = MapTypes.MapTypes$messageMapEntry.codec().decode(reader, reader.uint32(), { + const entry = MapTypes.MapTypes$messageMapEntry.codec().decode(r, r.uint32(), { limits: { value: opts.limits?.messageMap$value } @@ -952,7 +967,7 @@ export namespace MapTypes { throw new MaxSizeError('Decode error - map field "enumMap" had too many elements') } - const entry = MapTypes.MapTypes$enumMapEntry.codec().decode(reader, reader.uint32(), { + const entry = MapTypes.MapTypes$enumMapEntry.codec().decode(r, r.uint32(), { limits: { value: opts.limits?.enumMap$value } @@ -961,14 +976,14 @@ export namespace MapTypes { break } default: { - reader.skipType(tag & 7) + r.skipType(tag & 7) break } } } return obj - }, function * (reader, length, prefix, opts = {}) { + }, function * (r, length, prefix, opts = {}) { const obj = { stringMap: 0, intMap: 0, @@ -977,7 +992,7 @@ export namespace MapTypes { enumMap: 0 } - const end = length == null ? reader.len : reader.pos + length + const end = length == null ? r.len : r.pos + length if (prefix !== '.') { yield { @@ -987,8 +1002,8 @@ export namespace MapTypes { } } - while (reader.pos < end) { - const tag = reader.uint32() + while (r.pos < end) { + const tag = r.uint32() switch (tag >>> 3) { case 1: { @@ -996,7 +1011,7 @@ export namespace MapTypes { throw new MaxLengthError('Decode error - map field "stringMap" had too many elements') } - yield * MapTypes.MapTypes$stringMapEntry.codec().stream(reader, reader.uint32(), `${prefix}stringMap{}.`, { + yield * MapTypes.MapTypes$stringMapEntry.codec().stream(r, r.uint32(), `${prefix}stringMap{}.`, { limits: { value: opts.limits?.stringMap$value } @@ -1011,7 +1026,7 @@ export namespace MapTypes { throw new MaxLengthError('Decode error - map field "intMap" had too many elements') } - yield * MapTypes.MapTypes$intMapEntry.codec().stream(reader, reader.uint32(), `${prefix}intMap{}.`, { + yield * MapTypes.MapTypes$intMapEntry.codec().stream(r, r.uint32(), `${prefix}intMap{}.`, { limits: { value: opts.limits?.intMap$value } @@ -1026,7 +1041,7 @@ export namespace MapTypes { throw new MaxLengthError('Decode error - map field "boolMap" had too many elements') } - yield * MapTypes.MapTypes$boolMapEntry.codec().stream(reader, reader.uint32(), `${prefix}boolMap{}.`, { + yield * MapTypes.MapTypes$boolMapEntry.codec().stream(r, r.uint32(), `${prefix}boolMap{}.`, { limits: { value: opts.limits?.boolMap$value } @@ -1041,7 +1056,7 @@ export namespace MapTypes { throw new MaxLengthError('Decode error - map field "messageMap" had too many elements') } - yield * MapTypes.MapTypes$messageMapEntry.codec().stream(reader, reader.uint32(), `${prefix}messageMap{}.`, { + yield * MapTypes.MapTypes$messageMapEntry.codec().stream(r, r.uint32(), `${prefix}messageMap{}.`, { limits: { value: opts.limits?.messageMap$value } @@ -1056,7 +1071,7 @@ export namespace MapTypes { throw new MaxLengthError('Decode error - map field "enumMap" had too many elements') } - yield * MapTypes.MapTypes$enumMapEntry.codec().stream(reader, reader.uint32(), `${prefix}enumMap{}.`, { + yield * MapTypes.MapTypes$enumMapEntry.codec().stream(r, r.uint32(), `${prefix}enumMap{}.`, { limits: { value: opts.limits?.enumMap$value } @@ -1067,7 +1082,7 @@ export namespace MapTypes { break } default: { - reader.skipType(tag & 7) + r.skipType(tag & 7) break } } diff --git a/packages/protons/test/fixtures/noise.ts b/packages/protons/test/fixtures/noise.ts index 9b25a48..c5c1945 100644 --- a/packages/protons/test/fixtures/noise.ts +++ b/packages/protons/test/fixtures/noise.ts @@ -40,41 +40,41 @@ export namespace pb { if (opts.lengthDelimited !== false) { w.ldelim() } - }, (reader, length, opts = {}) => { + }, (r, length, opts = {}) => { const obj: any = { identityKey: uint8ArrayAlloc(0), identitySig: uint8ArrayAlloc(0), data: uint8ArrayAlloc(0) } - const end = length == null ? reader.len : reader.pos + length + const end = length == null ? r.len : r.pos + length - while (reader.pos < end) { - const tag = reader.uint32() + while (r.pos < end) { + const tag = r.uint32() switch (tag >>> 3) { case 1: { - obj.identityKey = reader.bytes() + obj.identityKey = r.bytes() break } case 2: { - obj.identitySig = reader.bytes() + obj.identitySig = r.bytes() break } case 3: { - obj.data = reader.bytes() + obj.data = r.bytes() break } default: { - reader.skipType(tag & 7) + r.skipType(tag & 7) break } } } return obj - }, function * (reader, length, prefix, opts = {}) { - const end = length == null ? reader.len : reader.pos + length + }, function * (r, length, prefix, opts = {}) { + const end = length == null ? r.len : r.pos + length if (prefix !== '.') { yield { @@ -84,33 +84,33 @@ export namespace pb { } } - while (reader.pos < end) { - const tag = reader.uint32() + while (r.pos < end) { + const tag = r.uint32() switch (tag >>> 3) { case 1: { yield { field: `${prefix}identityKey`, - value: reader.bytes() + value: r.bytes() } break } case 2: { yield { field: `${prefix}identitySig`, - value: reader.bytes() + value: r.bytes() } break } case 3: { yield { field: `${prefix}data`, - value: reader.bytes() + value: r.bytes() } break } default: { - reader.skipType(tag & 7) + r.skipType(tag & 7) break } } @@ -169,25 +169,25 @@ export namespace pb { if (opts.lengthDelimited !== false) { w.ldelim() } - }, (reader, length, opts = {}) => { + }, (r, length, opts = {}) => { const obj: any = {} - const end = length == null ? reader.len : reader.pos + length + const end = length == null ? r.len : r.pos + length - while (reader.pos < end) { - const tag = reader.uint32() + while (r.pos < end) { + const tag = r.uint32() switch (tag >>> 3) { default: { - reader.skipType(tag & 7) + r.skipType(tag & 7) break } } } return obj - }, function * (reader, length, prefix, opts = {}) { - const end = length == null ? reader.len : reader.pos + length + }, function * (r, length, prefix, opts = {}) { + const end = length == null ? r.len : r.pos + length if (prefix !== '.') { yield { @@ -197,12 +197,12 @@ export namespace pb { } } - while (reader.pos < end) { - const tag = reader.uint32() + while (r.pos < end) { + const tag = r.uint32() switch (tag >>> 3) { default: { - reader.skipType(tag & 7) + r.skipType(tag & 7) break } } diff --git a/packages/protons/test/fixtures/oneof.ts b/packages/protons/test/fixtures/oneof.ts index 0a01cd1..1f4f0fd 100644 --- a/packages/protons/test/fixtures/oneof.ts +++ b/packages/protons/test/fixtures/oneof.ts @@ -82,39 +82,39 @@ export namespace OneOfMessage { if (opts.lengthDelimited !== false) { w.ldelim() } - }, (reader, length, opts = {}) => { + }, (r, length, opts = {}) => { const obj: any = { fieldFive: '' } - const end = length == null ? reader.len : reader.pos + length + const end = length == null ? r.len : r.pos + length - while (reader.pos < end) { - const tag = reader.uint32() + while (r.pos < end) { + const tag = r.uint32() switch (tag >>> 3) { case 1: { - obj.fieldOne = reader.string() + obj.fieldOne = r.string() break } case 2: { - obj.fieldTwo = reader.string() + obj.fieldTwo = r.string() break } case 3: { - obj.fieldThree = EnumType.codec().decode(reader) + obj.fieldThree = EnumType.codec().decode(r) break } case 4: { - obj.fieldFour = EnumType.codec().decode(reader) + obj.fieldFour = EnumType.codec().decode(r) break } case 5: { - obj.fieldFive = reader.string() + obj.fieldFive = r.string() break } default: { - reader.skipType(tag & 7) + r.skipType(tag & 7) break } } @@ -137,8 +137,8 @@ export namespace OneOfMessage { } return obj - }, function * (reader, length, prefix, opts = {}) { - const end = length == null ? reader.len : reader.pos + length + }, function * (r, length, prefix, opts = {}) { + const end = length == null ? r.len : r.pos + length if (prefix !== '.') { yield { @@ -148,47 +148,47 @@ export namespace OneOfMessage { } } - while (reader.pos < end) { - const tag = reader.uint32() + while (r.pos < end) { + const tag = r.uint32() switch (tag >>> 3) { case 1: { yield { field: `${prefix}fieldOne`, - value: reader.string() + value: r.string() } break } case 2: { yield { field: `${prefix}fieldTwo`, - value: reader.string() + value: r.string() } break } case 3: { yield { field: `${prefix}fieldThree`, - value: EnumType.codec().decode(reader) + value: EnumType.codec().decode(r) } break } case 4: { yield { field: `${prefix}fieldFour`, - value: EnumType.codec().decode(reader) + value: EnumType.codec().decode(r) } break } case 5: { yield { field: `${prefix}fieldFive`, - value: reader.string() + value: r.string() } break } default: { - reader.skipType(tag & 7) + r.skipType(tag & 7) break } } @@ -291,7 +291,7 @@ export namespace MessageWithoutOneOfs { if (opts.lengthDelimited !== false) { w.ldelim() } - }, (reader, length, opts = {}) => { + }, (r, length, opts = {}) => { const obj: any = { fieldOne: '', fieldTwo: '', @@ -300,42 +300,42 @@ export namespace MessageWithoutOneOfs { fieldFive: '' } - const end = length == null ? reader.len : reader.pos + length + const end = length == null ? r.len : r.pos + length - while (reader.pos < end) { - const tag = reader.uint32() + while (r.pos < end) { + const tag = r.uint32() switch (tag >>> 3) { case 1: { - obj.fieldOne = reader.string() + obj.fieldOne = r.string() break } case 2: { - obj.fieldTwo = reader.string() + obj.fieldTwo = r.string() break } case 3: { - obj.fieldThree = EnumType.codec().decode(reader) + obj.fieldThree = EnumType.codec().decode(r) break } case 4: { - obj.fieldFour = EnumType.codec().decode(reader) + obj.fieldFour = EnumType.codec().decode(r) break } case 5: { - obj.fieldFive = reader.string() + obj.fieldFive = r.string() break } default: { - reader.skipType(tag & 7) + r.skipType(tag & 7) break } } } return obj - }, function * (reader, length, prefix, opts = {}) { - const end = length == null ? reader.len : reader.pos + length + }, function * (r, length, prefix, opts = {}) { + const end = length == null ? r.len : r.pos + length if (prefix !== '.') { yield { @@ -345,47 +345,47 @@ export namespace MessageWithoutOneOfs { } } - while (reader.pos < end) { - const tag = reader.uint32() + while (r.pos < end) { + const tag = r.uint32() switch (tag >>> 3) { case 1: { yield { field: `${prefix}fieldOne`, - value: reader.string() + value: r.string() } break } case 2: { yield { field: `${prefix}fieldTwo`, - value: reader.string() + value: r.string() } break } case 3: { yield { field: `${prefix}fieldThree`, - value: EnumType.codec().decode(reader) + value: EnumType.codec().decode(r) } break } case 4: { yield { field: `${prefix}fieldFour`, - value: EnumType.codec().decode(reader) + value: EnumType.codec().decode(r) } break } case 5: { yield { field: `${prefix}fieldFive`, - value: reader.string() + value: r.string() } break } default: { - reader.skipType(tag & 7) + r.skipType(tag & 7) break } } diff --git a/packages/protons/test/fixtures/optional.ts b/packages/protons/test/fixtures/optional.ts index 6e407a1..4eb1cda 100644 --- a/packages/protons/test/fixtures/optional.ts +++ b/packages/protons/test/fixtures/optional.ts @@ -48,33 +48,33 @@ export namespace OptionalSubMessage { if (opts.lengthDelimited !== false) { w.ldelim() } - }, (reader, length, opts = {}) => { + }, (r, length, opts = {}) => { const obj: any = {} - const end = length == null ? reader.len : reader.pos + length + const end = length == null ? r.len : r.pos + length - while (reader.pos < end) { - const tag = reader.uint32() + while (r.pos < end) { + const tag = r.uint32() switch (tag >>> 3) { case 1: { - obj.foo = reader.string() + obj.foo = r.string() break } case 2: { - obj.bar = reader.int32() + obj.bar = r.int32() break } default: { - reader.skipType(tag & 7) + r.skipType(tag & 7) break } } } return obj - }, function * (reader, length, prefix, opts = {}) { - const end = length == null ? reader.len : reader.pos + length + }, function * (r, length, prefix, opts = {}) { + const end = length == null ? r.len : r.pos + length if (prefix !== '.') { yield { @@ -84,26 +84,26 @@ export namespace OptionalSubMessage { } } - while (reader.pos < end) { - const tag = reader.uint32() + while (r.pos < end) { + const tag = r.uint32() switch (tag >>> 3) { case 1: { yield { field: `${prefix}foo`, - value: reader.string() + value: r.string() } break } case 2: { yield { field: `${prefix}bar`, - value: reader.int32() + value: r.int32() } break } default: { - reader.skipType(tag & 7) + r.skipType(tag & 7) break } } @@ -263,95 +263,95 @@ export namespace Optional { if (opts.lengthDelimited !== false) { w.ldelim() } - }, (reader, length, opts = {}) => { + }, (r, length, opts = {}) => { const obj: any = {} - const end = length == null ? reader.len : reader.pos + length + const end = length == null ? r.len : r.pos + length - while (reader.pos < end) { - const tag = reader.uint32() + while (r.pos < end) { + const tag = r.uint32() switch (tag >>> 3) { case 1: { - obj.double = reader.double() + obj.double = r.double() break } case 2: { - obj.float = reader.float() + obj.float = r.float() break } case 3: { - obj.int32 = reader.int32() + obj.int32 = r.int32() break } case 4: { - obj.int64 = reader.int64() + obj.int64 = r.int64() break } case 5: { - obj.uint32 = reader.uint32() + obj.uint32 = r.uint32() break } case 6: { - obj.uint64 = reader.uint64() + obj.uint64 = r.uint64() break } case 7: { - obj.sint32 = reader.sint32() + obj.sint32 = r.sint32() break } case 8: { - obj.sint64 = reader.sint64() + obj.sint64 = r.sint64() break } case 9: { - obj.fixed32 = reader.fixed32() + obj.fixed32 = r.fixed32() break } case 10: { - obj.fixed64 = reader.fixed64() + obj.fixed64 = r.fixed64() break } case 11: { - obj.sfixed32 = reader.sfixed32() + obj.sfixed32 = r.sfixed32() break } case 12: { - obj.sfixed64 = reader.sfixed64() + obj.sfixed64 = r.sfixed64() break } case 13: { - obj.bool = reader.bool() + obj.bool = r.bool() break } case 14: { - obj.string = reader.string() + obj.string = r.string() break } case 15: { - obj.bytes = reader.bytes() + obj.bytes = r.bytes() break } case 16: { - obj.enum = OptionalEnum.codec().decode(reader) + obj.enum = OptionalEnum.codec().decode(r) break } case 17: { - obj.subMessage = OptionalSubMessage.codec().decode(reader, reader.uint32(), { + obj.subMessage = OptionalSubMessage.codec().decode(r, r.uint32(), { limits: opts.limits?.subMessage }) break } default: { - reader.skipType(tag & 7) + r.skipType(tag & 7) break } } } return obj - }, function * (reader, length, prefix, opts = {}) { - const end = length == null ? reader.len : reader.pos + length + }, function * (r, length, prefix, opts = {}) { + const end = length == null ? r.len : r.pos + length if (prefix !== '.') { yield { @@ -361,131 +361,131 @@ export namespace Optional { } } - while (reader.pos < end) { - const tag = reader.uint32() + while (r.pos < end) { + const tag = r.uint32() switch (tag >>> 3) { case 1: { yield { field: `${prefix}double`, - value: reader.double() + value: r.double() } break } case 2: { yield { field: `${prefix}float`, - value: reader.float() + value: r.float() } break } case 3: { yield { field: `${prefix}int32`, - value: reader.int32() + value: r.int32() } break } case 4: { yield { field: `${prefix}int64`, - value: reader.int64() + value: r.int64() } break } case 5: { yield { field: `${prefix}uint32`, - value: reader.uint32() + value: r.uint32() } break } case 6: { yield { field: `${prefix}uint64`, - value: reader.uint64() + value: r.uint64() } break } case 7: { yield { field: `${prefix}sint32`, - value: reader.sint32() + value: r.sint32() } break } case 8: { yield { field: `${prefix}sint64`, - value: reader.sint64() + value: r.sint64() } break } case 9: { yield { field: `${prefix}fixed32`, - value: reader.fixed32() + value: r.fixed32() } break } case 10: { yield { field: `${prefix}fixed64`, - value: reader.fixed64() + value: r.fixed64() } break } case 11: { yield { field: `${prefix}sfixed32`, - value: reader.sfixed32() + value: r.sfixed32() } break } case 12: { yield { field: `${prefix}sfixed64`, - value: reader.sfixed64() + value: r.sfixed64() } break } case 13: { yield { field: `${prefix}bool`, - value: reader.bool() + value: r.bool() } break } case 14: { yield { field: `${prefix}string`, - value: reader.string() + value: r.string() } break } case 15: { yield { field: `${prefix}bytes`, - value: reader.bytes() + value: r.bytes() } break } case 16: { yield { field: `${prefix}enum`, - value: OptionalEnum.codec().decode(reader) + value: OptionalEnum.codec().decode(r) } break } case 17: { - yield * OptionalSubMessage.codec().stream(reader, reader.uint32(), `${prefix}subMessage.`, { + yield * OptionalSubMessage.codec().stream(r, r.uint32(), `${prefix}subMessage.`, { limits: opts.limits?.subMessage }) break } default: { - reader.skipType(tag & 7) + r.skipType(tag & 7) break } } diff --git a/packages/protons/test/fixtures/packed.proto b/packages/protons/test/fixtures/packed.proto new file mode 100644 index 0000000..ba434b6 --- /dev/null +++ b/packages/protons/test/fixtures/packed.proto @@ -0,0 +1,86 @@ +syntax = "proto3"; + +message SpecPacked { + string str = 4; + repeated int32 packed = 5; +} + +message DefaultPackedTypes { + repeated double doubles = 1; + repeated float floats = 2; + repeated int32 int32s = 3; + repeated int64 int64s = 4; + repeated uint32 uint32s = 5; + repeated uint64 uint64s = 6; + repeated sint32 sint32s = 7; + repeated sint64 sint64s = 8; + repeated fixed32 fixed32s = 9; + repeated fixed64 fixed64s = 10; + repeated sfixed32 sfixed32s = 11; + repeated sfixed64 sfixed64s = 12; + repeated bool bools = 13; +} + +message PackedTypes { + repeated double doubles = 1 [packed=true]; + repeated float floats = 2 [packed=true]; + repeated int32 int32s = 3 [packed=true]; + repeated int64 int64s = 4 [packed=true]; + repeated uint32 uint32s = 5 [packed=true]; + repeated uint64 uint64s = 6 [packed=true]; + repeated sint32 sint32s = 7 [packed=true]; + repeated sint64 sint64s = 8 [packed=true]; + repeated fixed32 fixed32s = 9 [packed=true]; + repeated fixed64 fixed64s = 10 [packed=true]; + repeated sfixed32 sfixed32s = 11 [packed=true]; + repeated sfixed64 sfixed64s = 12 [packed=true]; + repeated bool bools = 13 [packed=true]; +} + +message ExpandedTypes { + repeated double doubles = 1 [packed=false]; + repeated float floats = 2 [packed=false]; + repeated int32 int32s = 3 [packed=false]; + repeated int64 int64s = 4 [packed=false]; + repeated uint32 uint32s = 5 [packed=false]; + repeated uint64 uint64s = 6 [packed=false]; + repeated sint32 sint32s = 7 [packed=false]; + repeated sint64 sint64s = 8 [packed=false]; + repeated fixed32 fixed32s = 9 [packed=false]; + repeated fixed64 fixed64s = 10 [packed=false]; + repeated sfixed32 sfixed32s = 11 [packed=false]; + repeated sfixed64 sfixed64s = 12 [packed=false]; + repeated bool bools = 13 [packed=false]; +} + +message NewOptionPackedTypes { + repeated double doubles = 1 [features.repeated_field_encoding=PACKED]; + repeated float floats = 2 [features.repeated_field_encoding=PACKED]; + repeated int32 int32s = 3 [features.repeated_field_encoding=PACKED]; + repeated int64 int64s = 4 [features.repeated_field_encoding=PACKED]; + repeated uint32 uint32s = 5 [features.repeated_field_encoding=PACKED]; + repeated uint64 uint64s = 6 [features.repeated_field_encoding=PACKED]; + repeated sint32 sint32s = 7 [features.repeated_field_encoding=PACKED]; + repeated sint64 sint64s = 8 [features.repeated_field_encoding=PACKED]; + repeated fixed32 fixed32s = 9 [features.repeated_field_encoding=PACKED]; + repeated fixed64 fixed64s = 10 [features.repeated_field_encoding=PACKED]; + repeated sfixed32 sfixed32s = 11 [features.repeated_field_encoding=PACKED]; + repeated sfixed64 sfixed64s = 12 [features.repeated_field_encoding=PACKED]; + repeated bool bools = 13 [features.repeated_field_encoding=PACKED]; +} + +message NewOptionExpandedTypes { + repeated double doubles = 1 [features.repeated_field_encoding=EXPANDED]; + repeated float floats = 2 [features.repeated_field_encoding=EXPANDED]; + repeated int32 int32s = 3 [features.repeated_field_encoding=EXPANDED]; + repeated int64 int64s = 4 [features.repeated_field_encoding=EXPANDED]; + repeated uint32 uint32s = 5 [features.repeated_field_encoding=EXPANDED]; + repeated uint64 uint64s = 6 [features.repeated_field_encoding=EXPANDED]; + repeated sint32 sint32s = 7 [features.repeated_field_encoding=EXPANDED]; + repeated sint64 sint64s = 8 [features.repeated_field_encoding=EXPANDED]; + repeated fixed32 fixed32s = 9 [features.repeated_field_encoding=EXPANDED]; + repeated fixed64 fixed64s = 10 [features.repeated_field_encoding=EXPANDED]; + repeated sfixed32 sfixed32s = 11 [features.repeated_field_encoding=EXPANDED]; + repeated sfixed64 sfixed64s = 12 [features.repeated_field_encoding=EXPANDED]; + repeated bool bools = 13 [features.repeated_field_encoding=EXPANDED]; +} diff --git a/packages/protons/test/fixtures/packed.ts b/packages/protons/test/fixtures/packed.ts new file mode 100644 index 0000000..2c66df8 --- /dev/null +++ b/packages/protons/test/fixtures/packed.ts @@ -0,0 +1,3710 @@ +import { decodeMessage, encodeMessage, MaxLengthError, message, reader, streamMessage } from 'protons-runtime' +import type { Codec, DecodeOptions } from 'protons-runtime' +import type { Uint8ArrayList } from 'uint8arraylist' + +export interface SpecPacked { + str: string + packed: number[] +} + +export namespace SpecPacked { + let _codec: Codec + + export const codec = (): Codec => { + if (_codec == null) { + _codec = message((obj, w, opts = {}) => { + if (opts.lengthDelimited !== false) { + w.fork() + } + + if ((obj.str != null && obj.str !== '')) { + w.uint32(34) + w.string(obj.str) + } + + if (obj.packed != null && obj.packed.length > 0) { + w.uint32(42) + w.fork() + + for (const value of obj.packed) { + w.int32(value) + } + + w.ldelim() + } + + if (opts.lengthDelimited !== false) { + w.ldelim() + } + }, (r, length, opts = {}) => { + const obj: any = { + str: '', + packed: [] + } + + const end = length == null ? r.len : r.pos + length + + while (r.pos < end) { + const tag = r.uint32() + + switch (tag >>> 3) { + case 4: { + obj.str = r.string() + break + } + case 5: { + const b = r.bytes() + const r2 = reader(b) + + while (r2.pos < r2.len) { + if (opts.limits?.packed != null && obj.packed.length === opts.limits.packed) { + throw new MaxLengthError('Decode error - repeated field "packed" had too many elements') + } + + obj.packed.push(r2.int32()) + } + + break + } + default: { + r.skipType(tag & 7) + break + } + } + } + + return obj + }, function * (r, length, prefix, opts = {}) { + const obj = { + packed: 0 + } + + const end = length == null ? r.len : r.pos + length + + if (prefix !== '.') { + yield { + field: prefix.endsWith('.') ? prefix.substring(0, prefix.length - 1) : prefix, + type: 'start', + message: 'SpecPacked' + } + } + + while (r.pos < end) { + const tag = r.uint32() + + switch (tag >>> 3) { + case 4: { + yield { + field: `${prefix}str`, + value: r.string() + } + break + } + case 5: { + const b = r.bytes() + const r2 = reader(b) + + while (r2.pos < r2.len) { + if (opts.limits?.packed != null && obj.packed === opts.limits.packed) { + throw new MaxLengthError('Streaming decode error - repeated field "packed" had too many elements') + } + + yield { + field: `${prefix}packed[]`, + index: obj.packed, + value: r2.int32() + } + + obj.packed++ + } + + break + } + default: { + r.skipType(tag & 7) + break + } + } + } + + if (prefix !== '.') { + yield { + field: prefix.endsWith('.') ? prefix.substring(0, prefix.length - 1) : prefix, + type: 'end', + message: 'SpecPacked' + } + } + }) + } + + return _codec + } + + export interface SpecPackedStrFieldEvent { + field: '.str' + value: string + } + + export interface SpecPackedPackedFieldEvent { + field: '.packed[]' + index: number + value: number + } + + export function encode (obj: Partial): Uint8Array { + return encodeMessage(obj, SpecPacked.codec()) + } + + export function decode (buf: Uint8Array | Uint8ArrayList, opts?: DecodeOptions): SpecPacked { + return decodeMessage(buf, SpecPacked.codec(), opts) + } + + export function stream (buf: Uint8Array | Uint8ArrayList, opts?: DecodeOptions): Generator { + return streamMessage(buf, SpecPacked.codec(), opts) + } +} + +export interface DefaultPackedTypes { + doubles: number[] + floats: number[] + int32s: number[] + int64s: bigint[] + uint32s: number[] + uint64s: bigint[] + sint32s: number[] + sint64s: bigint[] + fixed32s: number[] + fixed64s: bigint[] + sfixed32s: number[] + sfixed64s: bigint[] + bools: boolean[] +} + +export namespace DefaultPackedTypes { + let _codec: Codec + + export const codec = (): Codec => { + if (_codec == null) { + _codec = message((obj, w, opts = {}) => { + if (opts.lengthDelimited !== false) { + w.fork() + } + + if (obj.doubles != null && obj.doubles.length > 0) { + w.uint32(10) + w.fork() + + for (const value of obj.doubles) { + w.double(value) + } + + w.ldelim() + } + + if (obj.floats != null && obj.floats.length > 0) { + w.uint32(18) + w.fork() + + for (const value of obj.floats) { + w.float(value) + } + + w.ldelim() + } + + if (obj.int32s != null && obj.int32s.length > 0) { + w.uint32(26) + w.fork() + + for (const value of obj.int32s) { + w.int32(value) + } + + w.ldelim() + } + + if (obj.int64s != null && obj.int64s.length > 0) { + w.uint32(34) + w.fork() + + for (const value of obj.int64s) { + w.int64(value) + } + + w.ldelim() + } + + if (obj.uint32s != null && obj.uint32s.length > 0) { + w.uint32(42) + w.fork() + + for (const value of obj.uint32s) { + w.uint32(value) + } + + w.ldelim() + } + + if (obj.uint64s != null && obj.uint64s.length > 0) { + w.uint32(50) + w.fork() + + for (const value of obj.uint64s) { + w.uint64(value) + } + + w.ldelim() + } + + if (obj.sint32s != null && obj.sint32s.length > 0) { + w.uint32(58) + w.fork() + + for (const value of obj.sint32s) { + w.sint32(value) + } + + w.ldelim() + } + + if (obj.sint64s != null && obj.sint64s.length > 0) { + w.uint32(66) + w.fork() + + for (const value of obj.sint64s) { + w.sint64(value) + } + + w.ldelim() + } + + if (obj.fixed32s != null && obj.fixed32s.length > 0) { + w.uint32(74) + w.fork() + + for (const value of obj.fixed32s) { + w.fixed32(value) + } + + w.ldelim() + } + + if (obj.fixed64s != null && obj.fixed64s.length > 0) { + w.uint32(82) + w.fork() + + for (const value of obj.fixed64s) { + w.fixed64(value) + } + + w.ldelim() + } + + if (obj.sfixed32s != null && obj.sfixed32s.length > 0) { + w.uint32(90) + w.fork() + + for (const value of obj.sfixed32s) { + w.sfixed32(value) + } + + w.ldelim() + } + + if (obj.sfixed64s != null && obj.sfixed64s.length > 0) { + w.uint32(98) + w.fork() + + for (const value of obj.sfixed64s) { + w.sfixed64(value) + } + + w.ldelim() + } + + if (obj.bools != null && obj.bools.length > 0) { + w.uint32(106) + w.fork() + + for (const value of obj.bools) { + w.bool(value) + } + + w.ldelim() + } + + if (opts.lengthDelimited !== false) { + w.ldelim() + } + }, (r, length, opts = {}) => { + const obj: any = { + doubles: [], + floats: [], + int32s: [], + int64s: [], + uint32s: [], + uint64s: [], + sint32s: [], + sint64s: [], + fixed32s: [], + fixed64s: [], + sfixed32s: [], + sfixed64s: [], + bools: [] + } + + const end = length == null ? r.len : r.pos + length + + while (r.pos < end) { + const tag = r.uint32() + + switch (tag >>> 3) { + case 1: { + const b = r.bytes() + const r2 = reader(b) + + while (r2.pos < r2.len) { + if (opts.limits?.doubles != null && obj.doubles.length === opts.limits.doubles) { + throw new MaxLengthError('Decode error - repeated field "doubles" had too many elements') + } + + obj.doubles.push(r2.double()) + } + + break + } + case 2: { + const b = r.bytes() + const r2 = reader(b) + + while (r2.pos < r2.len) { + if (opts.limits?.floats != null && obj.floats.length === opts.limits.floats) { + throw new MaxLengthError('Decode error - repeated field "floats" had too many elements') + } + + obj.floats.push(r2.float()) + } + + break + } + case 3: { + const b = r.bytes() + const r2 = reader(b) + + while (r2.pos < r2.len) { + if (opts.limits?.int32s != null && obj.int32s.length === opts.limits.int32s) { + throw new MaxLengthError('Decode error - repeated field "int32s" had too many elements') + } + + obj.int32s.push(r2.int32()) + } + + break + } + case 4: { + const b = r.bytes() + const r2 = reader(b) + + while (r2.pos < r2.len) { + if (opts.limits?.int64s != null && obj.int64s.length === opts.limits.int64s) { + throw new MaxLengthError('Decode error - repeated field "int64s" had too many elements') + } + + obj.int64s.push(r2.int64()) + } + + break + } + case 5: { + const b = r.bytes() + const r2 = reader(b) + + while (r2.pos < r2.len) { + if (opts.limits?.uint32s != null && obj.uint32s.length === opts.limits.uint32s) { + throw new MaxLengthError('Decode error - repeated field "uint32s" had too many elements') + } + + obj.uint32s.push(r2.uint32()) + } + + break + } + case 6: { + const b = r.bytes() + const r2 = reader(b) + + while (r2.pos < r2.len) { + if (opts.limits?.uint64s != null && obj.uint64s.length === opts.limits.uint64s) { + throw new MaxLengthError('Decode error - repeated field "uint64s" had too many elements') + } + + obj.uint64s.push(r2.uint64()) + } + + break + } + case 7: { + const b = r.bytes() + const r2 = reader(b) + + while (r2.pos < r2.len) { + if (opts.limits?.sint32s != null && obj.sint32s.length === opts.limits.sint32s) { + throw new MaxLengthError('Decode error - repeated field "sint32s" had too many elements') + } + + obj.sint32s.push(r2.sint32()) + } + + break + } + case 8: { + const b = r.bytes() + const r2 = reader(b) + + while (r2.pos < r2.len) { + if (opts.limits?.sint64s != null && obj.sint64s.length === opts.limits.sint64s) { + throw new MaxLengthError('Decode error - repeated field "sint64s" had too many elements') + } + + obj.sint64s.push(r2.sint64()) + } + + break + } + case 9: { + const b = r.bytes() + const r2 = reader(b) + + while (r2.pos < r2.len) { + if (opts.limits?.fixed32s != null && obj.fixed32s.length === opts.limits.fixed32s) { + throw new MaxLengthError('Decode error - repeated field "fixed32s" had too many elements') + } + + obj.fixed32s.push(r2.fixed32()) + } + + break + } + case 10: { + const b = r.bytes() + const r2 = reader(b) + + while (r2.pos < r2.len) { + if (opts.limits?.fixed64s != null && obj.fixed64s.length === opts.limits.fixed64s) { + throw new MaxLengthError('Decode error - repeated field "fixed64s" had too many elements') + } + + obj.fixed64s.push(r2.fixed64()) + } + + break + } + case 11: { + const b = r.bytes() + const r2 = reader(b) + + while (r2.pos < r2.len) { + if (opts.limits?.sfixed32s != null && obj.sfixed32s.length === opts.limits.sfixed32s) { + throw new MaxLengthError('Decode error - repeated field "sfixed32s" had too many elements') + } + + obj.sfixed32s.push(r2.sfixed32()) + } + + break + } + case 12: { + const b = r.bytes() + const r2 = reader(b) + + while (r2.pos < r2.len) { + if (opts.limits?.sfixed64s != null && obj.sfixed64s.length === opts.limits.sfixed64s) { + throw new MaxLengthError('Decode error - repeated field "sfixed64s" had too many elements') + } + + obj.sfixed64s.push(r2.sfixed64()) + } + + break + } + case 13: { + const b = r.bytes() + const r2 = reader(b) + + while (r2.pos < r2.len) { + if (opts.limits?.bools != null && obj.bools.length === opts.limits.bools) { + throw new MaxLengthError('Decode error - repeated field "bools" had too many elements') + } + + obj.bools.push(r2.bool()) + } + + break + } + default: { + r.skipType(tag & 7) + break + } + } + } + + return obj + }, function * (r, length, prefix, opts = {}) { + const obj = { + doubles: 0, + floats: 0, + int32s: 0, + int64s: 0, + uint32s: 0, + uint64s: 0, + sint32s: 0, + sint64s: 0, + fixed32s: 0, + fixed64s: 0, + sfixed32s: 0, + sfixed64s: 0, + bools: 0 + } + + const end = length == null ? r.len : r.pos + length + + if (prefix !== '.') { + yield { + field: prefix.endsWith('.') ? prefix.substring(0, prefix.length - 1) : prefix, + type: 'start', + message: 'DefaultPackedTypes' + } + } + + while (r.pos < end) { + const tag = r.uint32() + + switch (tag >>> 3) { + case 1: { + const b = r.bytes() + const r2 = reader(b) + + while (r2.pos < r2.len) { + if (opts.limits?.doubles != null && obj.doubles === opts.limits.doubles) { + throw new MaxLengthError('Streaming decode error - repeated field "doubles" had too many elements') + } + + yield { + field: `${prefix}doubles[]`, + index: obj.doubles, + value: r2.double() + } + + obj.doubles++ + } + + break + } + case 2: { + const b = r.bytes() + const r2 = reader(b) + + while (r2.pos < r2.len) { + if (opts.limits?.floats != null && obj.floats === opts.limits.floats) { + throw new MaxLengthError('Streaming decode error - repeated field "floats" had too many elements') + } + + yield { + field: `${prefix}floats[]`, + index: obj.floats, + value: r2.float() + } + + obj.floats++ + } + + break + } + case 3: { + const b = r.bytes() + const r2 = reader(b) + + while (r2.pos < r2.len) { + if (opts.limits?.int32s != null && obj.int32s === opts.limits.int32s) { + throw new MaxLengthError('Streaming decode error - repeated field "int32s" had too many elements') + } + + yield { + field: `${prefix}int32s[]`, + index: obj.int32s, + value: r2.int32() + } + + obj.int32s++ + } + + break + } + case 4: { + const b = r.bytes() + const r2 = reader(b) + + while (r2.pos < r2.len) { + if (opts.limits?.int64s != null && obj.int64s === opts.limits.int64s) { + throw new MaxLengthError('Streaming decode error - repeated field "int64s" had too many elements') + } + + yield { + field: `${prefix}int64s[]`, + index: obj.int64s, + value: r2.int64() + } + + obj.int64s++ + } + + break + } + case 5: { + const b = r.bytes() + const r2 = reader(b) + + while (r2.pos < r2.len) { + if (opts.limits?.uint32s != null && obj.uint32s === opts.limits.uint32s) { + throw new MaxLengthError('Streaming decode error - repeated field "uint32s" had too many elements') + } + + yield { + field: `${prefix}uint32s[]`, + index: obj.uint32s, + value: r2.uint32() + } + + obj.uint32s++ + } + + break + } + case 6: { + const b = r.bytes() + const r2 = reader(b) + + while (r2.pos < r2.len) { + if (opts.limits?.uint64s != null && obj.uint64s === opts.limits.uint64s) { + throw new MaxLengthError('Streaming decode error - repeated field "uint64s" had too many elements') + } + + yield { + field: `${prefix}uint64s[]`, + index: obj.uint64s, + value: r2.uint64() + } + + obj.uint64s++ + } + + break + } + case 7: { + const b = r.bytes() + const r2 = reader(b) + + while (r2.pos < r2.len) { + if (opts.limits?.sint32s != null && obj.sint32s === opts.limits.sint32s) { + throw new MaxLengthError('Streaming decode error - repeated field "sint32s" had too many elements') + } + + yield { + field: `${prefix}sint32s[]`, + index: obj.sint32s, + value: r2.sint32() + } + + obj.sint32s++ + } + + break + } + case 8: { + const b = r.bytes() + const r2 = reader(b) + + while (r2.pos < r2.len) { + if (opts.limits?.sint64s != null && obj.sint64s === opts.limits.sint64s) { + throw new MaxLengthError('Streaming decode error - repeated field "sint64s" had too many elements') + } + + yield { + field: `${prefix}sint64s[]`, + index: obj.sint64s, + value: r2.sint64() + } + + obj.sint64s++ + } + + break + } + case 9: { + const b = r.bytes() + const r2 = reader(b) + + while (r2.pos < r2.len) { + if (opts.limits?.fixed32s != null && obj.fixed32s === opts.limits.fixed32s) { + throw new MaxLengthError('Streaming decode error - repeated field "fixed32s" had too many elements') + } + + yield { + field: `${prefix}fixed32s[]`, + index: obj.fixed32s, + value: r2.fixed32() + } + + obj.fixed32s++ + } + + break + } + case 10: { + const b = r.bytes() + const r2 = reader(b) + + while (r2.pos < r2.len) { + if (opts.limits?.fixed64s != null && obj.fixed64s === opts.limits.fixed64s) { + throw new MaxLengthError('Streaming decode error - repeated field "fixed64s" had too many elements') + } + + yield { + field: `${prefix}fixed64s[]`, + index: obj.fixed64s, + value: r2.fixed64() + } + + obj.fixed64s++ + } + + break + } + case 11: { + const b = r.bytes() + const r2 = reader(b) + + while (r2.pos < r2.len) { + if (opts.limits?.sfixed32s != null && obj.sfixed32s === opts.limits.sfixed32s) { + throw new MaxLengthError('Streaming decode error - repeated field "sfixed32s" had too many elements') + } + + yield { + field: `${prefix}sfixed32s[]`, + index: obj.sfixed32s, + value: r2.sfixed32() + } + + obj.sfixed32s++ + } + + break + } + case 12: { + const b = r.bytes() + const r2 = reader(b) + + while (r2.pos < r2.len) { + if (opts.limits?.sfixed64s != null && obj.sfixed64s === opts.limits.sfixed64s) { + throw new MaxLengthError('Streaming decode error - repeated field "sfixed64s" had too many elements') + } + + yield { + field: `${prefix}sfixed64s[]`, + index: obj.sfixed64s, + value: r2.sfixed64() + } + + obj.sfixed64s++ + } + + break + } + case 13: { + const b = r.bytes() + const r2 = reader(b) + + while (r2.pos < r2.len) { + if (opts.limits?.bools != null && obj.bools === opts.limits.bools) { + throw new MaxLengthError('Streaming decode error - repeated field "bools" had too many elements') + } + + yield { + field: `${prefix}bools[]`, + index: obj.bools, + value: r2.bool() + } + + obj.bools++ + } + + break + } + default: { + r.skipType(tag & 7) + break + } + } + } + + if (prefix !== '.') { + yield { + field: prefix.endsWith('.') ? prefix.substring(0, prefix.length - 1) : prefix, + type: 'end', + message: 'DefaultPackedTypes' + } + } + }) + } + + return _codec + } + + export interface DefaultPackedTypesDoublesFieldEvent { + field: '.doubles[]' + index: number + value: number + } + + export interface DefaultPackedTypesFloatsFieldEvent { + field: '.floats[]' + index: number + value: number + } + + export interface DefaultPackedTypesInt32sFieldEvent { + field: '.int32s[]' + index: number + value: number + } + + export interface DefaultPackedTypesInt64sFieldEvent { + field: '.int64s[]' + index: number + value: bigint + } + + export interface DefaultPackedTypesUint32sFieldEvent { + field: '.uint32s[]' + index: number + value: number + } + + export interface DefaultPackedTypesUint64sFieldEvent { + field: '.uint64s[]' + index: number + value: bigint + } + + export interface DefaultPackedTypesSint32sFieldEvent { + field: '.sint32s[]' + index: number + value: number + } + + export interface DefaultPackedTypesSint64sFieldEvent { + field: '.sint64s[]' + index: number + value: bigint + } + + export interface DefaultPackedTypesFixed32sFieldEvent { + field: '.fixed32s[]' + index: number + value: number + } + + export interface DefaultPackedTypesFixed64sFieldEvent { + field: '.fixed64s[]' + index: number + value: bigint + } + + export interface DefaultPackedTypesSfixed32sFieldEvent { + field: '.sfixed32s[]' + index: number + value: number + } + + export interface DefaultPackedTypesSfixed64sFieldEvent { + field: '.sfixed64s[]' + index: number + value: bigint + } + + export interface DefaultPackedTypesBoolsFieldEvent { + field: '.bools[]' + index: number + value: boolean + } + + export function encode (obj: Partial): Uint8Array { + return encodeMessage(obj, DefaultPackedTypes.codec()) + } + + export function decode (buf: Uint8Array | Uint8ArrayList, opts?: DecodeOptions): DefaultPackedTypes { + return decodeMessage(buf, DefaultPackedTypes.codec(), opts) + } + + export function stream (buf: Uint8Array | Uint8ArrayList, opts?: DecodeOptions): Generator { + return streamMessage(buf, DefaultPackedTypes.codec(), opts) + } +} + +export interface PackedTypes { + doubles: number[] + floats: number[] + int32s: number[] + int64s: bigint[] + uint32s: number[] + uint64s: bigint[] + sint32s: number[] + sint64s: bigint[] + fixed32s: number[] + fixed64s: bigint[] + sfixed32s: number[] + sfixed64s: bigint[] + bools: boolean[] +} + +export namespace PackedTypes { + let _codec: Codec + + export const codec = (): Codec => { + if (_codec == null) { + _codec = message((obj, w, opts = {}) => { + if (opts.lengthDelimited !== false) { + w.fork() + } + + if (obj.doubles != null && obj.doubles.length > 0) { + w.uint32(10) + w.fork() + + for (const value of obj.doubles) { + w.double(value) + } + + w.ldelim() + } + + if (obj.floats != null && obj.floats.length > 0) { + w.uint32(18) + w.fork() + + for (const value of obj.floats) { + w.float(value) + } + + w.ldelim() + } + + if (obj.int32s != null && obj.int32s.length > 0) { + w.uint32(26) + w.fork() + + for (const value of obj.int32s) { + w.int32(value) + } + + w.ldelim() + } + + if (obj.int64s != null && obj.int64s.length > 0) { + w.uint32(34) + w.fork() + + for (const value of obj.int64s) { + w.int64(value) + } + + w.ldelim() + } + + if (obj.uint32s != null && obj.uint32s.length > 0) { + w.uint32(42) + w.fork() + + for (const value of obj.uint32s) { + w.uint32(value) + } + + w.ldelim() + } + + if (obj.uint64s != null && obj.uint64s.length > 0) { + w.uint32(50) + w.fork() + + for (const value of obj.uint64s) { + w.uint64(value) + } + + w.ldelim() + } + + if (obj.sint32s != null && obj.sint32s.length > 0) { + w.uint32(58) + w.fork() + + for (const value of obj.sint32s) { + w.sint32(value) + } + + w.ldelim() + } + + if (obj.sint64s != null && obj.sint64s.length > 0) { + w.uint32(66) + w.fork() + + for (const value of obj.sint64s) { + w.sint64(value) + } + + w.ldelim() + } + + if (obj.fixed32s != null && obj.fixed32s.length > 0) { + w.uint32(74) + w.fork() + + for (const value of obj.fixed32s) { + w.fixed32(value) + } + + w.ldelim() + } + + if (obj.fixed64s != null && obj.fixed64s.length > 0) { + w.uint32(82) + w.fork() + + for (const value of obj.fixed64s) { + w.fixed64(value) + } + + w.ldelim() + } + + if (obj.sfixed32s != null && obj.sfixed32s.length > 0) { + w.uint32(90) + w.fork() + + for (const value of obj.sfixed32s) { + w.sfixed32(value) + } + + w.ldelim() + } + + if (obj.sfixed64s != null && obj.sfixed64s.length > 0) { + w.uint32(98) + w.fork() + + for (const value of obj.sfixed64s) { + w.sfixed64(value) + } + + w.ldelim() + } + + if (obj.bools != null && obj.bools.length > 0) { + w.uint32(106) + w.fork() + + for (const value of obj.bools) { + w.bool(value) + } + + w.ldelim() + } + + if (opts.lengthDelimited !== false) { + w.ldelim() + } + }, (r, length, opts = {}) => { + const obj: any = { + doubles: [], + floats: [], + int32s: [], + int64s: [], + uint32s: [], + uint64s: [], + sint32s: [], + sint64s: [], + fixed32s: [], + fixed64s: [], + sfixed32s: [], + sfixed64s: [], + bools: [] + } + + const end = length == null ? r.len : r.pos + length + + while (r.pos < end) { + const tag = r.uint32() + + switch (tag >>> 3) { + case 1: { + const b = r.bytes() + const r2 = reader(b) + + while (r2.pos < r2.len) { + if (opts.limits?.doubles != null && obj.doubles.length === opts.limits.doubles) { + throw new MaxLengthError('Decode error - repeated field "doubles" had too many elements') + } + + obj.doubles.push(r2.double()) + } + + break + } + case 2: { + const b = r.bytes() + const r2 = reader(b) + + while (r2.pos < r2.len) { + if (opts.limits?.floats != null && obj.floats.length === opts.limits.floats) { + throw new MaxLengthError('Decode error - repeated field "floats" had too many elements') + } + + obj.floats.push(r2.float()) + } + + break + } + case 3: { + const b = r.bytes() + const r2 = reader(b) + + while (r2.pos < r2.len) { + if (opts.limits?.int32s != null && obj.int32s.length === opts.limits.int32s) { + throw new MaxLengthError('Decode error - repeated field "int32s" had too many elements') + } + + obj.int32s.push(r2.int32()) + } + + break + } + case 4: { + const b = r.bytes() + const r2 = reader(b) + + while (r2.pos < r2.len) { + if (opts.limits?.int64s != null && obj.int64s.length === opts.limits.int64s) { + throw new MaxLengthError('Decode error - repeated field "int64s" had too many elements') + } + + obj.int64s.push(r2.int64()) + } + + break + } + case 5: { + const b = r.bytes() + const r2 = reader(b) + + while (r2.pos < r2.len) { + if (opts.limits?.uint32s != null && obj.uint32s.length === opts.limits.uint32s) { + throw new MaxLengthError('Decode error - repeated field "uint32s" had too many elements') + } + + obj.uint32s.push(r2.uint32()) + } + + break + } + case 6: { + const b = r.bytes() + const r2 = reader(b) + + while (r2.pos < r2.len) { + if (opts.limits?.uint64s != null && obj.uint64s.length === opts.limits.uint64s) { + throw new MaxLengthError('Decode error - repeated field "uint64s" had too many elements') + } + + obj.uint64s.push(r2.uint64()) + } + + break + } + case 7: { + const b = r.bytes() + const r2 = reader(b) + + while (r2.pos < r2.len) { + if (opts.limits?.sint32s != null && obj.sint32s.length === opts.limits.sint32s) { + throw new MaxLengthError('Decode error - repeated field "sint32s" had too many elements') + } + + obj.sint32s.push(r2.sint32()) + } + + break + } + case 8: { + const b = r.bytes() + const r2 = reader(b) + + while (r2.pos < r2.len) { + if (opts.limits?.sint64s != null && obj.sint64s.length === opts.limits.sint64s) { + throw new MaxLengthError('Decode error - repeated field "sint64s" had too many elements') + } + + obj.sint64s.push(r2.sint64()) + } + + break + } + case 9: { + const b = r.bytes() + const r2 = reader(b) + + while (r2.pos < r2.len) { + if (opts.limits?.fixed32s != null && obj.fixed32s.length === opts.limits.fixed32s) { + throw new MaxLengthError('Decode error - repeated field "fixed32s" had too many elements') + } + + obj.fixed32s.push(r2.fixed32()) + } + + break + } + case 10: { + const b = r.bytes() + const r2 = reader(b) + + while (r2.pos < r2.len) { + if (opts.limits?.fixed64s != null && obj.fixed64s.length === opts.limits.fixed64s) { + throw new MaxLengthError('Decode error - repeated field "fixed64s" had too many elements') + } + + obj.fixed64s.push(r2.fixed64()) + } + + break + } + case 11: { + const b = r.bytes() + const r2 = reader(b) + + while (r2.pos < r2.len) { + if (opts.limits?.sfixed32s != null && obj.sfixed32s.length === opts.limits.sfixed32s) { + throw new MaxLengthError('Decode error - repeated field "sfixed32s" had too many elements') + } + + obj.sfixed32s.push(r2.sfixed32()) + } + + break + } + case 12: { + const b = r.bytes() + const r2 = reader(b) + + while (r2.pos < r2.len) { + if (opts.limits?.sfixed64s != null && obj.sfixed64s.length === opts.limits.sfixed64s) { + throw new MaxLengthError('Decode error - repeated field "sfixed64s" had too many elements') + } + + obj.sfixed64s.push(r2.sfixed64()) + } + + break + } + case 13: { + const b = r.bytes() + const r2 = reader(b) + + while (r2.pos < r2.len) { + if (opts.limits?.bools != null && obj.bools.length === opts.limits.bools) { + throw new MaxLengthError('Decode error - repeated field "bools" had too many elements') + } + + obj.bools.push(r2.bool()) + } + + break + } + default: { + r.skipType(tag & 7) + break + } + } + } + + return obj + }, function * (r, length, prefix, opts = {}) { + const obj = { + doubles: 0, + floats: 0, + int32s: 0, + int64s: 0, + uint32s: 0, + uint64s: 0, + sint32s: 0, + sint64s: 0, + fixed32s: 0, + fixed64s: 0, + sfixed32s: 0, + sfixed64s: 0, + bools: 0 + } + + const end = length == null ? r.len : r.pos + length + + if (prefix !== '.') { + yield { + field: prefix.endsWith('.') ? prefix.substring(0, prefix.length - 1) : prefix, + type: 'start', + message: 'PackedTypes' + } + } + + while (r.pos < end) { + const tag = r.uint32() + + switch (tag >>> 3) { + case 1: { + const b = r.bytes() + const r2 = reader(b) + + while (r2.pos < r2.len) { + if (opts.limits?.doubles != null && obj.doubles === opts.limits.doubles) { + throw new MaxLengthError('Streaming decode error - repeated field "doubles" had too many elements') + } + + yield { + field: `${prefix}doubles[]`, + index: obj.doubles, + value: r2.double() + } + + obj.doubles++ + } + + break + } + case 2: { + const b = r.bytes() + const r2 = reader(b) + + while (r2.pos < r2.len) { + if (opts.limits?.floats != null && obj.floats === opts.limits.floats) { + throw new MaxLengthError('Streaming decode error - repeated field "floats" had too many elements') + } + + yield { + field: `${prefix}floats[]`, + index: obj.floats, + value: r2.float() + } + + obj.floats++ + } + + break + } + case 3: { + const b = r.bytes() + const r2 = reader(b) + + while (r2.pos < r2.len) { + if (opts.limits?.int32s != null && obj.int32s === opts.limits.int32s) { + throw new MaxLengthError('Streaming decode error - repeated field "int32s" had too many elements') + } + + yield { + field: `${prefix}int32s[]`, + index: obj.int32s, + value: r2.int32() + } + + obj.int32s++ + } + + break + } + case 4: { + const b = r.bytes() + const r2 = reader(b) + + while (r2.pos < r2.len) { + if (opts.limits?.int64s != null && obj.int64s === opts.limits.int64s) { + throw new MaxLengthError('Streaming decode error - repeated field "int64s" had too many elements') + } + + yield { + field: `${prefix}int64s[]`, + index: obj.int64s, + value: r2.int64() + } + + obj.int64s++ + } + + break + } + case 5: { + const b = r.bytes() + const r2 = reader(b) + + while (r2.pos < r2.len) { + if (opts.limits?.uint32s != null && obj.uint32s === opts.limits.uint32s) { + throw new MaxLengthError('Streaming decode error - repeated field "uint32s" had too many elements') + } + + yield { + field: `${prefix}uint32s[]`, + index: obj.uint32s, + value: r2.uint32() + } + + obj.uint32s++ + } + + break + } + case 6: { + const b = r.bytes() + const r2 = reader(b) + + while (r2.pos < r2.len) { + if (opts.limits?.uint64s != null && obj.uint64s === opts.limits.uint64s) { + throw new MaxLengthError('Streaming decode error - repeated field "uint64s" had too many elements') + } + + yield { + field: `${prefix}uint64s[]`, + index: obj.uint64s, + value: r2.uint64() + } + + obj.uint64s++ + } + + break + } + case 7: { + const b = r.bytes() + const r2 = reader(b) + + while (r2.pos < r2.len) { + if (opts.limits?.sint32s != null && obj.sint32s === opts.limits.sint32s) { + throw new MaxLengthError('Streaming decode error - repeated field "sint32s" had too many elements') + } + + yield { + field: `${prefix}sint32s[]`, + index: obj.sint32s, + value: r2.sint32() + } + + obj.sint32s++ + } + + break + } + case 8: { + const b = r.bytes() + const r2 = reader(b) + + while (r2.pos < r2.len) { + if (opts.limits?.sint64s != null && obj.sint64s === opts.limits.sint64s) { + throw new MaxLengthError('Streaming decode error - repeated field "sint64s" had too many elements') + } + + yield { + field: `${prefix}sint64s[]`, + index: obj.sint64s, + value: r2.sint64() + } + + obj.sint64s++ + } + + break + } + case 9: { + const b = r.bytes() + const r2 = reader(b) + + while (r2.pos < r2.len) { + if (opts.limits?.fixed32s != null && obj.fixed32s === opts.limits.fixed32s) { + throw new MaxLengthError('Streaming decode error - repeated field "fixed32s" had too many elements') + } + + yield { + field: `${prefix}fixed32s[]`, + index: obj.fixed32s, + value: r2.fixed32() + } + + obj.fixed32s++ + } + + break + } + case 10: { + const b = r.bytes() + const r2 = reader(b) + + while (r2.pos < r2.len) { + if (opts.limits?.fixed64s != null && obj.fixed64s === opts.limits.fixed64s) { + throw new MaxLengthError('Streaming decode error - repeated field "fixed64s" had too many elements') + } + + yield { + field: `${prefix}fixed64s[]`, + index: obj.fixed64s, + value: r2.fixed64() + } + + obj.fixed64s++ + } + + break + } + case 11: { + const b = r.bytes() + const r2 = reader(b) + + while (r2.pos < r2.len) { + if (opts.limits?.sfixed32s != null && obj.sfixed32s === opts.limits.sfixed32s) { + throw new MaxLengthError('Streaming decode error - repeated field "sfixed32s" had too many elements') + } + + yield { + field: `${prefix}sfixed32s[]`, + index: obj.sfixed32s, + value: r2.sfixed32() + } + + obj.sfixed32s++ + } + + break + } + case 12: { + const b = r.bytes() + const r2 = reader(b) + + while (r2.pos < r2.len) { + if (opts.limits?.sfixed64s != null && obj.sfixed64s === opts.limits.sfixed64s) { + throw new MaxLengthError('Streaming decode error - repeated field "sfixed64s" had too many elements') + } + + yield { + field: `${prefix}sfixed64s[]`, + index: obj.sfixed64s, + value: r2.sfixed64() + } + + obj.sfixed64s++ + } + + break + } + case 13: { + const b = r.bytes() + const r2 = reader(b) + + while (r2.pos < r2.len) { + if (opts.limits?.bools != null && obj.bools === opts.limits.bools) { + throw new MaxLengthError('Streaming decode error - repeated field "bools" had too many elements') + } + + yield { + field: `${prefix}bools[]`, + index: obj.bools, + value: r2.bool() + } + + obj.bools++ + } + + break + } + default: { + r.skipType(tag & 7) + break + } + } + } + + if (prefix !== '.') { + yield { + field: prefix.endsWith('.') ? prefix.substring(0, prefix.length - 1) : prefix, + type: 'end', + message: 'PackedTypes' + } + } + }) + } + + return _codec + } + + export interface PackedTypesDoublesFieldEvent { + field: '.doubles[]' + index: number + value: number + } + + export interface PackedTypesFloatsFieldEvent { + field: '.floats[]' + index: number + value: number + } + + export interface PackedTypesInt32sFieldEvent { + field: '.int32s[]' + index: number + value: number + } + + export interface PackedTypesInt64sFieldEvent { + field: '.int64s[]' + index: number + value: bigint + } + + export interface PackedTypesUint32sFieldEvent { + field: '.uint32s[]' + index: number + value: number + } + + export interface PackedTypesUint64sFieldEvent { + field: '.uint64s[]' + index: number + value: bigint + } + + export interface PackedTypesSint32sFieldEvent { + field: '.sint32s[]' + index: number + value: number + } + + export interface PackedTypesSint64sFieldEvent { + field: '.sint64s[]' + index: number + value: bigint + } + + export interface PackedTypesFixed32sFieldEvent { + field: '.fixed32s[]' + index: number + value: number + } + + export interface PackedTypesFixed64sFieldEvent { + field: '.fixed64s[]' + index: number + value: bigint + } + + export interface PackedTypesSfixed32sFieldEvent { + field: '.sfixed32s[]' + index: number + value: number + } + + export interface PackedTypesSfixed64sFieldEvent { + field: '.sfixed64s[]' + index: number + value: bigint + } + + export interface PackedTypesBoolsFieldEvent { + field: '.bools[]' + index: number + value: boolean + } + + export function encode (obj: Partial): Uint8Array { + return encodeMessage(obj, PackedTypes.codec()) + } + + export function decode (buf: Uint8Array | Uint8ArrayList, opts?: DecodeOptions): PackedTypes { + return decodeMessage(buf, PackedTypes.codec(), opts) + } + + export function stream (buf: Uint8Array | Uint8ArrayList, opts?: DecodeOptions): Generator { + return streamMessage(buf, PackedTypes.codec(), opts) + } +} + +export interface ExpandedTypes { + doubles: number[] + floats: number[] + int32s: number[] + int64s: bigint[] + uint32s: number[] + uint64s: bigint[] + sint32s: number[] + sint64s: bigint[] + fixed32s: number[] + fixed64s: bigint[] + sfixed32s: number[] + sfixed64s: bigint[] + bools: boolean[] +} + +export namespace ExpandedTypes { + let _codec: Codec + + export const codec = (): Codec => { + if (_codec == null) { + _codec = message((obj, w, opts = {}) => { + if (opts.lengthDelimited !== false) { + w.fork() + } + + if (obj.doubles != null && obj.doubles.length > 0) { + for (const value of obj.doubles) { + w.uint32(9) + w.double(value) + } + } + + if (obj.floats != null && obj.floats.length > 0) { + for (const value of obj.floats) { + w.uint32(21) + w.float(value) + } + } + + if (obj.int32s != null && obj.int32s.length > 0) { + for (const value of obj.int32s) { + w.uint32(24) + w.int32(value) + } + } + + if (obj.int64s != null && obj.int64s.length > 0) { + for (const value of obj.int64s) { + w.uint32(32) + w.int64(value) + } + } + + if (obj.uint32s != null && obj.uint32s.length > 0) { + for (const value of obj.uint32s) { + w.uint32(40) + w.uint32(value) + } + } + + if (obj.uint64s != null && obj.uint64s.length > 0) { + for (const value of obj.uint64s) { + w.uint32(48) + w.uint64(value) + } + } + + if (obj.sint32s != null && obj.sint32s.length > 0) { + for (const value of obj.sint32s) { + w.uint32(56) + w.sint32(value) + } + } + + if (obj.sint64s != null && obj.sint64s.length > 0) { + for (const value of obj.sint64s) { + w.uint32(64) + w.sint64(value) + } + } + + if (obj.fixed32s != null && obj.fixed32s.length > 0) { + for (const value of obj.fixed32s) { + w.uint32(77) + w.fixed32(value) + } + } + + if (obj.fixed64s != null && obj.fixed64s.length > 0) { + for (const value of obj.fixed64s) { + w.uint32(81) + w.fixed64(value) + } + } + + if (obj.sfixed32s != null && obj.sfixed32s.length > 0) { + for (const value of obj.sfixed32s) { + w.uint32(93) + w.sfixed32(value) + } + } + + if (obj.sfixed64s != null && obj.sfixed64s.length > 0) { + for (const value of obj.sfixed64s) { + w.uint32(97) + w.sfixed64(value) + } + } + + if (obj.bools != null && obj.bools.length > 0) { + for (const value of obj.bools) { + w.uint32(104) + w.bool(value) + } + } + + if (opts.lengthDelimited !== false) { + w.ldelim() + } + }, (r, length, opts = {}) => { + const obj: any = { + doubles: [], + floats: [], + int32s: [], + int64s: [], + uint32s: [], + uint64s: [], + sint32s: [], + sint64s: [], + fixed32s: [], + fixed64s: [], + sfixed32s: [], + sfixed64s: [], + bools: [] + } + + const end = length == null ? r.len : r.pos + length + + while (r.pos < end) { + const tag = r.uint32() + + switch (tag >>> 3) { + case 1: { + if (opts.limits?.doubles != null && obj.doubles.length === opts.limits.doubles) { + throw new MaxLengthError('Decode error - repeated field "doubles" had too many elements') + } + + obj.doubles.push(r.double()) + break + } + case 2: { + if (opts.limits?.floats != null && obj.floats.length === opts.limits.floats) { + throw new MaxLengthError('Decode error - repeated field "floats" had too many elements') + } + + obj.floats.push(r.float()) + break + } + case 3: { + if (opts.limits?.int32s != null && obj.int32s.length === opts.limits.int32s) { + throw new MaxLengthError('Decode error - repeated field "int32s" had too many elements') + } + + obj.int32s.push(r.int32()) + break + } + case 4: { + if (opts.limits?.int64s != null && obj.int64s.length === opts.limits.int64s) { + throw new MaxLengthError('Decode error - repeated field "int64s" had too many elements') + } + + obj.int64s.push(r.int64()) + break + } + case 5: { + if (opts.limits?.uint32s != null && obj.uint32s.length === opts.limits.uint32s) { + throw new MaxLengthError('Decode error - repeated field "uint32s" had too many elements') + } + + obj.uint32s.push(r.uint32()) + break + } + case 6: { + if (opts.limits?.uint64s != null && obj.uint64s.length === opts.limits.uint64s) { + throw new MaxLengthError('Decode error - repeated field "uint64s" had too many elements') + } + + obj.uint64s.push(r.uint64()) + break + } + case 7: { + if (opts.limits?.sint32s != null && obj.sint32s.length === opts.limits.sint32s) { + throw new MaxLengthError('Decode error - repeated field "sint32s" had too many elements') + } + + obj.sint32s.push(r.sint32()) + break + } + case 8: { + if (opts.limits?.sint64s != null && obj.sint64s.length === opts.limits.sint64s) { + throw new MaxLengthError('Decode error - repeated field "sint64s" had too many elements') + } + + obj.sint64s.push(r.sint64()) + break + } + case 9: { + if (opts.limits?.fixed32s != null && obj.fixed32s.length === opts.limits.fixed32s) { + throw new MaxLengthError('Decode error - repeated field "fixed32s" had too many elements') + } + + obj.fixed32s.push(r.fixed32()) + break + } + case 10: { + if (opts.limits?.fixed64s != null && obj.fixed64s.length === opts.limits.fixed64s) { + throw new MaxLengthError('Decode error - repeated field "fixed64s" had too many elements') + } + + obj.fixed64s.push(r.fixed64()) + break + } + case 11: { + if (opts.limits?.sfixed32s != null && obj.sfixed32s.length === opts.limits.sfixed32s) { + throw new MaxLengthError('Decode error - repeated field "sfixed32s" had too many elements') + } + + obj.sfixed32s.push(r.sfixed32()) + break + } + case 12: { + if (opts.limits?.sfixed64s != null && obj.sfixed64s.length === opts.limits.sfixed64s) { + throw new MaxLengthError('Decode error - repeated field "sfixed64s" had too many elements') + } + + obj.sfixed64s.push(r.sfixed64()) + break + } + case 13: { + if (opts.limits?.bools != null && obj.bools.length === opts.limits.bools) { + throw new MaxLengthError('Decode error - repeated field "bools" had too many elements') + } + + obj.bools.push(r.bool()) + break + } + default: { + r.skipType(tag & 7) + break + } + } + } + + return obj + }, function * (r, length, prefix, opts = {}) { + const obj = { + doubles: 0, + floats: 0, + int32s: 0, + int64s: 0, + uint32s: 0, + uint64s: 0, + sint32s: 0, + sint64s: 0, + fixed32s: 0, + fixed64s: 0, + sfixed32s: 0, + sfixed64s: 0, + bools: 0 + } + + const end = length == null ? r.len : r.pos + length + + if (prefix !== '.') { + yield { + field: prefix.endsWith('.') ? prefix.substring(0, prefix.length - 1) : prefix, + type: 'start', + message: 'ExpandedTypes' + } + } + + while (r.pos < end) { + const tag = r.uint32() + + switch (tag >>> 3) { + case 1: { + if (opts.limits?.doubles != null && obj.doubles === opts.limits.doubles) { + throw new MaxLengthError('Streaming decode error - repeated field "doubles" had too many elements') + } + + yield { + field: `${prefix}doubles[]`, + index: obj.doubles, + value: r.double() + } + + obj.doubles++ + + break + } + case 2: { + if (opts.limits?.floats != null && obj.floats === opts.limits.floats) { + throw new MaxLengthError('Streaming decode error - repeated field "floats" had too many elements') + } + + yield { + field: `${prefix}floats[]`, + index: obj.floats, + value: r.float() + } + + obj.floats++ + + break + } + case 3: { + if (opts.limits?.int32s != null && obj.int32s === opts.limits.int32s) { + throw new MaxLengthError('Streaming decode error - repeated field "int32s" had too many elements') + } + + yield { + field: `${prefix}int32s[]`, + index: obj.int32s, + value: r.int32() + } + + obj.int32s++ + + break + } + case 4: { + if (opts.limits?.int64s != null && obj.int64s === opts.limits.int64s) { + throw new MaxLengthError('Streaming decode error - repeated field "int64s" had too many elements') + } + + yield { + field: `${prefix}int64s[]`, + index: obj.int64s, + value: r.int64() + } + + obj.int64s++ + + break + } + case 5: { + if (opts.limits?.uint32s != null && obj.uint32s === opts.limits.uint32s) { + throw new MaxLengthError('Streaming decode error - repeated field "uint32s" had too many elements') + } + + yield { + field: `${prefix}uint32s[]`, + index: obj.uint32s, + value: r.uint32() + } + + obj.uint32s++ + + break + } + case 6: { + if (opts.limits?.uint64s != null && obj.uint64s === opts.limits.uint64s) { + throw new MaxLengthError('Streaming decode error - repeated field "uint64s" had too many elements') + } + + yield { + field: `${prefix}uint64s[]`, + index: obj.uint64s, + value: r.uint64() + } + + obj.uint64s++ + + break + } + case 7: { + if (opts.limits?.sint32s != null && obj.sint32s === opts.limits.sint32s) { + throw new MaxLengthError('Streaming decode error - repeated field "sint32s" had too many elements') + } + + yield { + field: `${prefix}sint32s[]`, + index: obj.sint32s, + value: r.sint32() + } + + obj.sint32s++ + + break + } + case 8: { + if (opts.limits?.sint64s != null && obj.sint64s === opts.limits.sint64s) { + throw new MaxLengthError('Streaming decode error - repeated field "sint64s" had too many elements') + } + + yield { + field: `${prefix}sint64s[]`, + index: obj.sint64s, + value: r.sint64() + } + + obj.sint64s++ + + break + } + case 9: { + if (opts.limits?.fixed32s != null && obj.fixed32s === opts.limits.fixed32s) { + throw new MaxLengthError('Streaming decode error - repeated field "fixed32s" had too many elements') + } + + yield { + field: `${prefix}fixed32s[]`, + index: obj.fixed32s, + value: r.fixed32() + } + + obj.fixed32s++ + + break + } + case 10: { + if (opts.limits?.fixed64s != null && obj.fixed64s === opts.limits.fixed64s) { + throw new MaxLengthError('Streaming decode error - repeated field "fixed64s" had too many elements') + } + + yield { + field: `${prefix}fixed64s[]`, + index: obj.fixed64s, + value: r.fixed64() + } + + obj.fixed64s++ + + break + } + case 11: { + if (opts.limits?.sfixed32s != null && obj.sfixed32s === opts.limits.sfixed32s) { + throw new MaxLengthError('Streaming decode error - repeated field "sfixed32s" had too many elements') + } + + yield { + field: `${prefix}sfixed32s[]`, + index: obj.sfixed32s, + value: r.sfixed32() + } + + obj.sfixed32s++ + + break + } + case 12: { + if (opts.limits?.sfixed64s != null && obj.sfixed64s === opts.limits.sfixed64s) { + throw new MaxLengthError('Streaming decode error - repeated field "sfixed64s" had too many elements') + } + + yield { + field: `${prefix}sfixed64s[]`, + index: obj.sfixed64s, + value: r.sfixed64() + } + + obj.sfixed64s++ + + break + } + case 13: { + if (opts.limits?.bools != null && obj.bools === opts.limits.bools) { + throw new MaxLengthError('Streaming decode error - repeated field "bools" had too many elements') + } + + yield { + field: `${prefix}bools[]`, + index: obj.bools, + value: r.bool() + } + + obj.bools++ + + break + } + default: { + r.skipType(tag & 7) + break + } + } + } + + if (prefix !== '.') { + yield { + field: prefix.endsWith('.') ? prefix.substring(0, prefix.length - 1) : prefix, + type: 'end', + message: 'ExpandedTypes' + } + } + }) + } + + return _codec + } + + export interface ExpandedTypesDoublesFieldEvent { + field: '.doubles[]' + index: number + value: number + } + + export interface ExpandedTypesFloatsFieldEvent { + field: '.floats[]' + index: number + value: number + } + + export interface ExpandedTypesInt32sFieldEvent { + field: '.int32s[]' + index: number + value: number + } + + export interface ExpandedTypesInt64sFieldEvent { + field: '.int64s[]' + index: number + value: bigint + } + + export interface ExpandedTypesUint32sFieldEvent { + field: '.uint32s[]' + index: number + value: number + } + + export interface ExpandedTypesUint64sFieldEvent { + field: '.uint64s[]' + index: number + value: bigint + } + + export interface ExpandedTypesSint32sFieldEvent { + field: '.sint32s[]' + index: number + value: number + } + + export interface ExpandedTypesSint64sFieldEvent { + field: '.sint64s[]' + index: number + value: bigint + } + + export interface ExpandedTypesFixed32sFieldEvent { + field: '.fixed32s[]' + index: number + value: number + } + + export interface ExpandedTypesFixed64sFieldEvent { + field: '.fixed64s[]' + index: number + value: bigint + } + + export interface ExpandedTypesSfixed32sFieldEvent { + field: '.sfixed32s[]' + index: number + value: number + } + + export interface ExpandedTypesSfixed64sFieldEvent { + field: '.sfixed64s[]' + index: number + value: bigint + } + + export interface ExpandedTypesBoolsFieldEvent { + field: '.bools[]' + index: number + value: boolean + } + + export function encode (obj: Partial): Uint8Array { + return encodeMessage(obj, ExpandedTypes.codec()) + } + + export function decode (buf: Uint8Array | Uint8ArrayList, opts?: DecodeOptions): ExpandedTypes { + return decodeMessage(buf, ExpandedTypes.codec(), opts) + } + + export function stream (buf: Uint8Array | Uint8ArrayList, opts?: DecodeOptions): Generator { + return streamMessage(buf, ExpandedTypes.codec(), opts) + } +} + +export interface NewOptionPackedTypes { + doubles: number[] + floats: number[] + int32s: number[] + int64s: bigint[] + uint32s: number[] + uint64s: bigint[] + sint32s: number[] + sint64s: bigint[] + fixed32s: number[] + fixed64s: bigint[] + sfixed32s: number[] + sfixed64s: bigint[] + bools: boolean[] +} + +export namespace NewOptionPackedTypes { + let _codec: Codec + + export const codec = (): Codec => { + if (_codec == null) { + _codec = message((obj, w, opts = {}) => { + if (opts.lengthDelimited !== false) { + w.fork() + } + + if (obj.doubles != null && obj.doubles.length > 0) { + w.uint32(10) + w.fork() + + for (const value of obj.doubles) { + w.double(value) + } + + w.ldelim() + } + + if (obj.floats != null && obj.floats.length > 0) { + w.uint32(18) + w.fork() + + for (const value of obj.floats) { + w.float(value) + } + + w.ldelim() + } + + if (obj.int32s != null && obj.int32s.length > 0) { + w.uint32(26) + w.fork() + + for (const value of obj.int32s) { + w.int32(value) + } + + w.ldelim() + } + + if (obj.int64s != null && obj.int64s.length > 0) { + w.uint32(34) + w.fork() + + for (const value of obj.int64s) { + w.int64(value) + } + + w.ldelim() + } + + if (obj.uint32s != null && obj.uint32s.length > 0) { + w.uint32(42) + w.fork() + + for (const value of obj.uint32s) { + w.uint32(value) + } + + w.ldelim() + } + + if (obj.uint64s != null && obj.uint64s.length > 0) { + w.uint32(50) + w.fork() + + for (const value of obj.uint64s) { + w.uint64(value) + } + + w.ldelim() + } + + if (obj.sint32s != null && obj.sint32s.length > 0) { + w.uint32(58) + w.fork() + + for (const value of obj.sint32s) { + w.sint32(value) + } + + w.ldelim() + } + + if (obj.sint64s != null && obj.sint64s.length > 0) { + w.uint32(66) + w.fork() + + for (const value of obj.sint64s) { + w.sint64(value) + } + + w.ldelim() + } + + if (obj.fixed32s != null && obj.fixed32s.length > 0) { + w.uint32(74) + w.fork() + + for (const value of obj.fixed32s) { + w.fixed32(value) + } + + w.ldelim() + } + + if (obj.fixed64s != null && obj.fixed64s.length > 0) { + w.uint32(82) + w.fork() + + for (const value of obj.fixed64s) { + w.fixed64(value) + } + + w.ldelim() + } + + if (obj.sfixed32s != null && obj.sfixed32s.length > 0) { + w.uint32(90) + w.fork() + + for (const value of obj.sfixed32s) { + w.sfixed32(value) + } + + w.ldelim() + } + + if (obj.sfixed64s != null && obj.sfixed64s.length > 0) { + w.uint32(98) + w.fork() + + for (const value of obj.sfixed64s) { + w.sfixed64(value) + } + + w.ldelim() + } + + if (obj.bools != null && obj.bools.length > 0) { + w.uint32(106) + w.fork() + + for (const value of obj.bools) { + w.bool(value) + } + + w.ldelim() + } + + if (opts.lengthDelimited !== false) { + w.ldelim() + } + }, (r, length, opts = {}) => { + const obj: any = { + doubles: [], + floats: [], + int32s: [], + int64s: [], + uint32s: [], + uint64s: [], + sint32s: [], + sint64s: [], + fixed32s: [], + fixed64s: [], + sfixed32s: [], + sfixed64s: [], + bools: [] + } + + const end = length == null ? r.len : r.pos + length + + while (r.pos < end) { + const tag = r.uint32() + + switch (tag >>> 3) { + case 1: { + const b = r.bytes() + const r2 = reader(b) + + while (r2.pos < r2.len) { + if (opts.limits?.doubles != null && obj.doubles.length === opts.limits.doubles) { + throw new MaxLengthError('Decode error - repeated field "doubles" had too many elements') + } + + obj.doubles.push(r2.double()) + } + + break + } + case 2: { + const b = r.bytes() + const r2 = reader(b) + + while (r2.pos < r2.len) { + if (opts.limits?.floats != null && obj.floats.length === opts.limits.floats) { + throw new MaxLengthError('Decode error - repeated field "floats" had too many elements') + } + + obj.floats.push(r2.float()) + } + + break + } + case 3: { + const b = r.bytes() + const r2 = reader(b) + + while (r2.pos < r2.len) { + if (opts.limits?.int32s != null && obj.int32s.length === opts.limits.int32s) { + throw new MaxLengthError('Decode error - repeated field "int32s" had too many elements') + } + + obj.int32s.push(r2.int32()) + } + + break + } + case 4: { + const b = r.bytes() + const r2 = reader(b) + + while (r2.pos < r2.len) { + if (opts.limits?.int64s != null && obj.int64s.length === opts.limits.int64s) { + throw new MaxLengthError('Decode error - repeated field "int64s" had too many elements') + } + + obj.int64s.push(r2.int64()) + } + + break + } + case 5: { + const b = r.bytes() + const r2 = reader(b) + + while (r2.pos < r2.len) { + if (opts.limits?.uint32s != null && obj.uint32s.length === opts.limits.uint32s) { + throw new MaxLengthError('Decode error - repeated field "uint32s" had too many elements') + } + + obj.uint32s.push(r2.uint32()) + } + + break + } + case 6: { + const b = r.bytes() + const r2 = reader(b) + + while (r2.pos < r2.len) { + if (opts.limits?.uint64s != null && obj.uint64s.length === opts.limits.uint64s) { + throw new MaxLengthError('Decode error - repeated field "uint64s" had too many elements') + } + + obj.uint64s.push(r2.uint64()) + } + + break + } + case 7: { + const b = r.bytes() + const r2 = reader(b) + + while (r2.pos < r2.len) { + if (opts.limits?.sint32s != null && obj.sint32s.length === opts.limits.sint32s) { + throw new MaxLengthError('Decode error - repeated field "sint32s" had too many elements') + } + + obj.sint32s.push(r2.sint32()) + } + + break + } + case 8: { + const b = r.bytes() + const r2 = reader(b) + + while (r2.pos < r2.len) { + if (opts.limits?.sint64s != null && obj.sint64s.length === opts.limits.sint64s) { + throw new MaxLengthError('Decode error - repeated field "sint64s" had too many elements') + } + + obj.sint64s.push(r2.sint64()) + } + + break + } + case 9: { + const b = r.bytes() + const r2 = reader(b) + + while (r2.pos < r2.len) { + if (opts.limits?.fixed32s != null && obj.fixed32s.length === opts.limits.fixed32s) { + throw new MaxLengthError('Decode error - repeated field "fixed32s" had too many elements') + } + + obj.fixed32s.push(r2.fixed32()) + } + + break + } + case 10: { + const b = r.bytes() + const r2 = reader(b) + + while (r2.pos < r2.len) { + if (opts.limits?.fixed64s != null && obj.fixed64s.length === opts.limits.fixed64s) { + throw new MaxLengthError('Decode error - repeated field "fixed64s" had too many elements') + } + + obj.fixed64s.push(r2.fixed64()) + } + + break + } + case 11: { + const b = r.bytes() + const r2 = reader(b) + + while (r2.pos < r2.len) { + if (opts.limits?.sfixed32s != null && obj.sfixed32s.length === opts.limits.sfixed32s) { + throw new MaxLengthError('Decode error - repeated field "sfixed32s" had too many elements') + } + + obj.sfixed32s.push(r2.sfixed32()) + } + + break + } + case 12: { + const b = r.bytes() + const r2 = reader(b) + + while (r2.pos < r2.len) { + if (opts.limits?.sfixed64s != null && obj.sfixed64s.length === opts.limits.sfixed64s) { + throw new MaxLengthError('Decode error - repeated field "sfixed64s" had too many elements') + } + + obj.sfixed64s.push(r2.sfixed64()) + } + + break + } + case 13: { + const b = r.bytes() + const r2 = reader(b) + + while (r2.pos < r2.len) { + if (opts.limits?.bools != null && obj.bools.length === opts.limits.bools) { + throw new MaxLengthError('Decode error - repeated field "bools" had too many elements') + } + + obj.bools.push(r2.bool()) + } + + break + } + default: { + r.skipType(tag & 7) + break + } + } + } + + return obj + }, function * (r, length, prefix, opts = {}) { + const obj = { + doubles: 0, + floats: 0, + int32s: 0, + int64s: 0, + uint32s: 0, + uint64s: 0, + sint32s: 0, + sint64s: 0, + fixed32s: 0, + fixed64s: 0, + sfixed32s: 0, + sfixed64s: 0, + bools: 0 + } + + const end = length == null ? r.len : r.pos + length + + if (prefix !== '.') { + yield { + field: prefix.endsWith('.') ? prefix.substring(0, prefix.length - 1) : prefix, + type: 'start', + message: 'NewOptionPackedTypes' + } + } + + while (r.pos < end) { + const tag = r.uint32() + + switch (tag >>> 3) { + case 1: { + const b = r.bytes() + const r2 = reader(b) + + while (r2.pos < r2.len) { + if (opts.limits?.doubles != null && obj.doubles === opts.limits.doubles) { + throw new MaxLengthError('Streaming decode error - repeated field "doubles" had too many elements') + } + + yield { + field: `${prefix}doubles[]`, + index: obj.doubles, + value: r2.double() + } + + obj.doubles++ + } + + break + } + case 2: { + const b = r.bytes() + const r2 = reader(b) + + while (r2.pos < r2.len) { + if (opts.limits?.floats != null && obj.floats === opts.limits.floats) { + throw new MaxLengthError('Streaming decode error - repeated field "floats" had too many elements') + } + + yield { + field: `${prefix}floats[]`, + index: obj.floats, + value: r2.float() + } + + obj.floats++ + } + + break + } + case 3: { + const b = r.bytes() + const r2 = reader(b) + + while (r2.pos < r2.len) { + if (opts.limits?.int32s != null && obj.int32s === opts.limits.int32s) { + throw new MaxLengthError('Streaming decode error - repeated field "int32s" had too many elements') + } + + yield { + field: `${prefix}int32s[]`, + index: obj.int32s, + value: r2.int32() + } + + obj.int32s++ + } + + break + } + case 4: { + const b = r.bytes() + const r2 = reader(b) + + while (r2.pos < r2.len) { + if (opts.limits?.int64s != null && obj.int64s === opts.limits.int64s) { + throw new MaxLengthError('Streaming decode error - repeated field "int64s" had too many elements') + } + + yield { + field: `${prefix}int64s[]`, + index: obj.int64s, + value: r2.int64() + } + + obj.int64s++ + } + + break + } + case 5: { + const b = r.bytes() + const r2 = reader(b) + + while (r2.pos < r2.len) { + if (opts.limits?.uint32s != null && obj.uint32s === opts.limits.uint32s) { + throw new MaxLengthError('Streaming decode error - repeated field "uint32s" had too many elements') + } + + yield { + field: `${prefix}uint32s[]`, + index: obj.uint32s, + value: r2.uint32() + } + + obj.uint32s++ + } + + break + } + case 6: { + const b = r.bytes() + const r2 = reader(b) + + while (r2.pos < r2.len) { + if (opts.limits?.uint64s != null && obj.uint64s === opts.limits.uint64s) { + throw new MaxLengthError('Streaming decode error - repeated field "uint64s" had too many elements') + } + + yield { + field: `${prefix}uint64s[]`, + index: obj.uint64s, + value: r2.uint64() + } + + obj.uint64s++ + } + + break + } + case 7: { + const b = r.bytes() + const r2 = reader(b) + + while (r2.pos < r2.len) { + if (opts.limits?.sint32s != null && obj.sint32s === opts.limits.sint32s) { + throw new MaxLengthError('Streaming decode error - repeated field "sint32s" had too many elements') + } + + yield { + field: `${prefix}sint32s[]`, + index: obj.sint32s, + value: r2.sint32() + } + + obj.sint32s++ + } + + break + } + case 8: { + const b = r.bytes() + const r2 = reader(b) + + while (r2.pos < r2.len) { + if (opts.limits?.sint64s != null && obj.sint64s === opts.limits.sint64s) { + throw new MaxLengthError('Streaming decode error - repeated field "sint64s" had too many elements') + } + + yield { + field: `${prefix}sint64s[]`, + index: obj.sint64s, + value: r2.sint64() + } + + obj.sint64s++ + } + + break + } + case 9: { + const b = r.bytes() + const r2 = reader(b) + + while (r2.pos < r2.len) { + if (opts.limits?.fixed32s != null && obj.fixed32s === opts.limits.fixed32s) { + throw new MaxLengthError('Streaming decode error - repeated field "fixed32s" had too many elements') + } + + yield { + field: `${prefix}fixed32s[]`, + index: obj.fixed32s, + value: r2.fixed32() + } + + obj.fixed32s++ + } + + break + } + case 10: { + const b = r.bytes() + const r2 = reader(b) + + while (r2.pos < r2.len) { + if (opts.limits?.fixed64s != null && obj.fixed64s === opts.limits.fixed64s) { + throw new MaxLengthError('Streaming decode error - repeated field "fixed64s" had too many elements') + } + + yield { + field: `${prefix}fixed64s[]`, + index: obj.fixed64s, + value: r2.fixed64() + } + + obj.fixed64s++ + } + + break + } + case 11: { + const b = r.bytes() + const r2 = reader(b) + + while (r2.pos < r2.len) { + if (opts.limits?.sfixed32s != null && obj.sfixed32s === opts.limits.sfixed32s) { + throw new MaxLengthError('Streaming decode error - repeated field "sfixed32s" had too many elements') + } + + yield { + field: `${prefix}sfixed32s[]`, + index: obj.sfixed32s, + value: r2.sfixed32() + } + + obj.sfixed32s++ + } + + break + } + case 12: { + const b = r.bytes() + const r2 = reader(b) + + while (r2.pos < r2.len) { + if (opts.limits?.sfixed64s != null && obj.sfixed64s === opts.limits.sfixed64s) { + throw new MaxLengthError('Streaming decode error - repeated field "sfixed64s" had too many elements') + } + + yield { + field: `${prefix}sfixed64s[]`, + index: obj.sfixed64s, + value: r2.sfixed64() + } + + obj.sfixed64s++ + } + + break + } + case 13: { + const b = r.bytes() + const r2 = reader(b) + + while (r2.pos < r2.len) { + if (opts.limits?.bools != null && obj.bools === opts.limits.bools) { + throw new MaxLengthError('Streaming decode error - repeated field "bools" had too many elements') + } + + yield { + field: `${prefix}bools[]`, + index: obj.bools, + value: r2.bool() + } + + obj.bools++ + } + + break + } + default: { + r.skipType(tag & 7) + break + } + } + } + + if (prefix !== '.') { + yield { + field: prefix.endsWith('.') ? prefix.substring(0, prefix.length - 1) : prefix, + type: 'end', + message: 'NewOptionPackedTypes' + } + } + }) + } + + return _codec + } + + export interface NewOptionPackedTypesDoublesFieldEvent { + field: '.doubles[]' + index: number + value: number + } + + export interface NewOptionPackedTypesFloatsFieldEvent { + field: '.floats[]' + index: number + value: number + } + + export interface NewOptionPackedTypesInt32sFieldEvent { + field: '.int32s[]' + index: number + value: number + } + + export interface NewOptionPackedTypesInt64sFieldEvent { + field: '.int64s[]' + index: number + value: bigint + } + + export interface NewOptionPackedTypesUint32sFieldEvent { + field: '.uint32s[]' + index: number + value: number + } + + export interface NewOptionPackedTypesUint64sFieldEvent { + field: '.uint64s[]' + index: number + value: bigint + } + + export interface NewOptionPackedTypesSint32sFieldEvent { + field: '.sint32s[]' + index: number + value: number + } + + export interface NewOptionPackedTypesSint64sFieldEvent { + field: '.sint64s[]' + index: number + value: bigint + } + + export interface NewOptionPackedTypesFixed32sFieldEvent { + field: '.fixed32s[]' + index: number + value: number + } + + export interface NewOptionPackedTypesFixed64sFieldEvent { + field: '.fixed64s[]' + index: number + value: bigint + } + + export interface NewOptionPackedTypesSfixed32sFieldEvent { + field: '.sfixed32s[]' + index: number + value: number + } + + export interface NewOptionPackedTypesSfixed64sFieldEvent { + field: '.sfixed64s[]' + index: number + value: bigint + } + + export interface NewOptionPackedTypesBoolsFieldEvent { + field: '.bools[]' + index: number + value: boolean + } + + export function encode (obj: Partial): Uint8Array { + return encodeMessage(obj, NewOptionPackedTypes.codec()) + } + + export function decode (buf: Uint8Array | Uint8ArrayList, opts?: DecodeOptions): NewOptionPackedTypes { + return decodeMessage(buf, NewOptionPackedTypes.codec(), opts) + } + + export function stream (buf: Uint8Array | Uint8ArrayList, opts?: DecodeOptions): Generator { + return streamMessage(buf, NewOptionPackedTypes.codec(), opts) + } +} + +export interface NewOptionExpandedTypes { + doubles: number[] + floats: number[] + int32s: number[] + int64s: bigint[] + uint32s: number[] + uint64s: bigint[] + sint32s: number[] + sint64s: bigint[] + fixed32s: number[] + fixed64s: bigint[] + sfixed32s: number[] + sfixed64s: bigint[] + bools: boolean[] +} + +export namespace NewOptionExpandedTypes { + let _codec: Codec + + export const codec = (): Codec => { + if (_codec == null) { + _codec = message((obj, w, opts = {}) => { + if (opts.lengthDelimited !== false) { + w.fork() + } + + if (obj.doubles != null && obj.doubles.length > 0) { + for (const value of obj.doubles) { + w.uint32(9) + w.double(value) + } + } + + if (obj.floats != null && obj.floats.length > 0) { + for (const value of obj.floats) { + w.uint32(21) + w.float(value) + } + } + + if (obj.int32s != null && obj.int32s.length > 0) { + for (const value of obj.int32s) { + w.uint32(24) + w.int32(value) + } + } + + if (obj.int64s != null && obj.int64s.length > 0) { + for (const value of obj.int64s) { + w.uint32(32) + w.int64(value) + } + } + + if (obj.uint32s != null && obj.uint32s.length > 0) { + for (const value of obj.uint32s) { + w.uint32(40) + w.uint32(value) + } + } + + if (obj.uint64s != null && obj.uint64s.length > 0) { + for (const value of obj.uint64s) { + w.uint32(48) + w.uint64(value) + } + } + + if (obj.sint32s != null && obj.sint32s.length > 0) { + for (const value of obj.sint32s) { + w.uint32(56) + w.sint32(value) + } + } + + if (obj.sint64s != null && obj.sint64s.length > 0) { + for (const value of obj.sint64s) { + w.uint32(64) + w.sint64(value) + } + } + + if (obj.fixed32s != null && obj.fixed32s.length > 0) { + for (const value of obj.fixed32s) { + w.uint32(77) + w.fixed32(value) + } + } + + if (obj.fixed64s != null && obj.fixed64s.length > 0) { + for (const value of obj.fixed64s) { + w.uint32(81) + w.fixed64(value) + } + } + + if (obj.sfixed32s != null && obj.sfixed32s.length > 0) { + for (const value of obj.sfixed32s) { + w.uint32(93) + w.sfixed32(value) + } + } + + if (obj.sfixed64s != null && obj.sfixed64s.length > 0) { + for (const value of obj.sfixed64s) { + w.uint32(97) + w.sfixed64(value) + } + } + + if (obj.bools != null && obj.bools.length > 0) { + for (const value of obj.bools) { + w.uint32(104) + w.bool(value) + } + } + + if (opts.lengthDelimited !== false) { + w.ldelim() + } + }, (r, length, opts = {}) => { + const obj: any = { + doubles: [], + floats: [], + int32s: [], + int64s: [], + uint32s: [], + uint64s: [], + sint32s: [], + sint64s: [], + fixed32s: [], + fixed64s: [], + sfixed32s: [], + sfixed64s: [], + bools: [] + } + + const end = length == null ? r.len : r.pos + length + + while (r.pos < end) { + const tag = r.uint32() + + switch (tag >>> 3) { + case 1: { + if (opts.limits?.doubles != null && obj.doubles.length === opts.limits.doubles) { + throw new MaxLengthError('Decode error - repeated field "doubles" had too many elements') + } + + obj.doubles.push(r.double()) + break + } + case 2: { + if (opts.limits?.floats != null && obj.floats.length === opts.limits.floats) { + throw new MaxLengthError('Decode error - repeated field "floats" had too many elements') + } + + obj.floats.push(r.float()) + break + } + case 3: { + if (opts.limits?.int32s != null && obj.int32s.length === opts.limits.int32s) { + throw new MaxLengthError('Decode error - repeated field "int32s" had too many elements') + } + + obj.int32s.push(r.int32()) + break + } + case 4: { + if (opts.limits?.int64s != null && obj.int64s.length === opts.limits.int64s) { + throw new MaxLengthError('Decode error - repeated field "int64s" had too many elements') + } + + obj.int64s.push(r.int64()) + break + } + case 5: { + if (opts.limits?.uint32s != null && obj.uint32s.length === opts.limits.uint32s) { + throw new MaxLengthError('Decode error - repeated field "uint32s" had too many elements') + } + + obj.uint32s.push(r.uint32()) + break + } + case 6: { + if (opts.limits?.uint64s != null && obj.uint64s.length === opts.limits.uint64s) { + throw new MaxLengthError('Decode error - repeated field "uint64s" had too many elements') + } + + obj.uint64s.push(r.uint64()) + break + } + case 7: { + if (opts.limits?.sint32s != null && obj.sint32s.length === opts.limits.sint32s) { + throw new MaxLengthError('Decode error - repeated field "sint32s" had too many elements') + } + + obj.sint32s.push(r.sint32()) + break + } + case 8: { + if (opts.limits?.sint64s != null && obj.sint64s.length === opts.limits.sint64s) { + throw new MaxLengthError('Decode error - repeated field "sint64s" had too many elements') + } + + obj.sint64s.push(r.sint64()) + break + } + case 9: { + if (opts.limits?.fixed32s != null && obj.fixed32s.length === opts.limits.fixed32s) { + throw new MaxLengthError('Decode error - repeated field "fixed32s" had too many elements') + } + + obj.fixed32s.push(r.fixed32()) + break + } + case 10: { + if (opts.limits?.fixed64s != null && obj.fixed64s.length === opts.limits.fixed64s) { + throw new MaxLengthError('Decode error - repeated field "fixed64s" had too many elements') + } + + obj.fixed64s.push(r.fixed64()) + break + } + case 11: { + if (opts.limits?.sfixed32s != null && obj.sfixed32s.length === opts.limits.sfixed32s) { + throw new MaxLengthError('Decode error - repeated field "sfixed32s" had too many elements') + } + + obj.sfixed32s.push(r.sfixed32()) + break + } + case 12: { + if (opts.limits?.sfixed64s != null && obj.sfixed64s.length === opts.limits.sfixed64s) { + throw new MaxLengthError('Decode error - repeated field "sfixed64s" had too many elements') + } + + obj.sfixed64s.push(r.sfixed64()) + break + } + case 13: { + if (opts.limits?.bools != null && obj.bools.length === opts.limits.bools) { + throw new MaxLengthError('Decode error - repeated field "bools" had too many elements') + } + + obj.bools.push(r.bool()) + break + } + default: { + r.skipType(tag & 7) + break + } + } + } + + return obj + }, function * (r, length, prefix, opts = {}) { + const obj = { + doubles: 0, + floats: 0, + int32s: 0, + int64s: 0, + uint32s: 0, + uint64s: 0, + sint32s: 0, + sint64s: 0, + fixed32s: 0, + fixed64s: 0, + sfixed32s: 0, + sfixed64s: 0, + bools: 0 + } + + const end = length == null ? r.len : r.pos + length + + if (prefix !== '.') { + yield { + field: prefix.endsWith('.') ? prefix.substring(0, prefix.length - 1) : prefix, + type: 'start', + message: 'NewOptionExpandedTypes' + } + } + + while (r.pos < end) { + const tag = r.uint32() + + switch (tag >>> 3) { + case 1: { + if (opts.limits?.doubles != null && obj.doubles === opts.limits.doubles) { + throw new MaxLengthError('Streaming decode error - repeated field "doubles" had too many elements') + } + + yield { + field: `${prefix}doubles[]`, + index: obj.doubles, + value: r.double() + } + + obj.doubles++ + + break + } + case 2: { + if (opts.limits?.floats != null && obj.floats === opts.limits.floats) { + throw new MaxLengthError('Streaming decode error - repeated field "floats" had too many elements') + } + + yield { + field: `${prefix}floats[]`, + index: obj.floats, + value: r.float() + } + + obj.floats++ + + break + } + case 3: { + if (opts.limits?.int32s != null && obj.int32s === opts.limits.int32s) { + throw new MaxLengthError('Streaming decode error - repeated field "int32s" had too many elements') + } + + yield { + field: `${prefix}int32s[]`, + index: obj.int32s, + value: r.int32() + } + + obj.int32s++ + + break + } + case 4: { + if (opts.limits?.int64s != null && obj.int64s === opts.limits.int64s) { + throw new MaxLengthError('Streaming decode error - repeated field "int64s" had too many elements') + } + + yield { + field: `${prefix}int64s[]`, + index: obj.int64s, + value: r.int64() + } + + obj.int64s++ + + break + } + case 5: { + if (opts.limits?.uint32s != null && obj.uint32s === opts.limits.uint32s) { + throw new MaxLengthError('Streaming decode error - repeated field "uint32s" had too many elements') + } + + yield { + field: `${prefix}uint32s[]`, + index: obj.uint32s, + value: r.uint32() + } + + obj.uint32s++ + + break + } + case 6: { + if (opts.limits?.uint64s != null && obj.uint64s === opts.limits.uint64s) { + throw new MaxLengthError('Streaming decode error - repeated field "uint64s" had too many elements') + } + + yield { + field: `${prefix}uint64s[]`, + index: obj.uint64s, + value: r.uint64() + } + + obj.uint64s++ + + break + } + case 7: { + if (opts.limits?.sint32s != null && obj.sint32s === opts.limits.sint32s) { + throw new MaxLengthError('Streaming decode error - repeated field "sint32s" had too many elements') + } + + yield { + field: `${prefix}sint32s[]`, + index: obj.sint32s, + value: r.sint32() + } + + obj.sint32s++ + + break + } + case 8: { + if (opts.limits?.sint64s != null && obj.sint64s === opts.limits.sint64s) { + throw new MaxLengthError('Streaming decode error - repeated field "sint64s" had too many elements') + } + + yield { + field: `${prefix}sint64s[]`, + index: obj.sint64s, + value: r.sint64() + } + + obj.sint64s++ + + break + } + case 9: { + if (opts.limits?.fixed32s != null && obj.fixed32s === opts.limits.fixed32s) { + throw new MaxLengthError('Streaming decode error - repeated field "fixed32s" had too many elements') + } + + yield { + field: `${prefix}fixed32s[]`, + index: obj.fixed32s, + value: r.fixed32() + } + + obj.fixed32s++ + + break + } + case 10: { + if (opts.limits?.fixed64s != null && obj.fixed64s === opts.limits.fixed64s) { + throw new MaxLengthError('Streaming decode error - repeated field "fixed64s" had too many elements') + } + + yield { + field: `${prefix}fixed64s[]`, + index: obj.fixed64s, + value: r.fixed64() + } + + obj.fixed64s++ + + break + } + case 11: { + if (opts.limits?.sfixed32s != null && obj.sfixed32s === opts.limits.sfixed32s) { + throw new MaxLengthError('Streaming decode error - repeated field "sfixed32s" had too many elements') + } + + yield { + field: `${prefix}sfixed32s[]`, + index: obj.sfixed32s, + value: r.sfixed32() + } + + obj.sfixed32s++ + + break + } + case 12: { + if (opts.limits?.sfixed64s != null && obj.sfixed64s === opts.limits.sfixed64s) { + throw new MaxLengthError('Streaming decode error - repeated field "sfixed64s" had too many elements') + } + + yield { + field: `${prefix}sfixed64s[]`, + index: obj.sfixed64s, + value: r.sfixed64() + } + + obj.sfixed64s++ + + break + } + case 13: { + if (opts.limits?.bools != null && obj.bools === opts.limits.bools) { + throw new MaxLengthError('Streaming decode error - repeated field "bools" had too many elements') + } + + yield { + field: `${prefix}bools[]`, + index: obj.bools, + value: r.bool() + } + + obj.bools++ + + break + } + default: { + r.skipType(tag & 7) + break + } + } + } + + if (prefix !== '.') { + yield { + field: prefix.endsWith('.') ? prefix.substring(0, prefix.length - 1) : prefix, + type: 'end', + message: 'NewOptionExpandedTypes' + } + } + }) + } + + return _codec + } + + export interface NewOptionExpandedTypesDoublesFieldEvent { + field: '.doubles[]' + index: number + value: number + } + + export interface NewOptionExpandedTypesFloatsFieldEvent { + field: '.floats[]' + index: number + value: number + } + + export interface NewOptionExpandedTypesInt32sFieldEvent { + field: '.int32s[]' + index: number + value: number + } + + export interface NewOptionExpandedTypesInt64sFieldEvent { + field: '.int64s[]' + index: number + value: bigint + } + + export interface NewOptionExpandedTypesUint32sFieldEvent { + field: '.uint32s[]' + index: number + value: number + } + + export interface NewOptionExpandedTypesUint64sFieldEvent { + field: '.uint64s[]' + index: number + value: bigint + } + + export interface NewOptionExpandedTypesSint32sFieldEvent { + field: '.sint32s[]' + index: number + value: number + } + + export interface NewOptionExpandedTypesSint64sFieldEvent { + field: '.sint64s[]' + index: number + value: bigint + } + + export interface NewOptionExpandedTypesFixed32sFieldEvent { + field: '.fixed32s[]' + index: number + value: number + } + + export interface NewOptionExpandedTypesFixed64sFieldEvent { + field: '.fixed64s[]' + index: number + value: bigint + } + + export interface NewOptionExpandedTypesSfixed32sFieldEvent { + field: '.sfixed32s[]' + index: number + value: number + } + + export interface NewOptionExpandedTypesSfixed64sFieldEvent { + field: '.sfixed64s[]' + index: number + value: bigint + } + + export interface NewOptionExpandedTypesBoolsFieldEvent { + field: '.bools[]' + index: number + value: boolean + } + + export function encode (obj: Partial): Uint8Array { + return encodeMessage(obj, NewOptionExpandedTypes.codec()) + } + + export function decode (buf: Uint8Array | Uint8ArrayList, opts?: DecodeOptions): NewOptionExpandedTypes { + return decodeMessage(buf, NewOptionExpandedTypes.codec(), opts) + } + + export function stream (buf: Uint8Array | Uint8ArrayList, opts?: DecodeOptions): Generator { + return streamMessage(buf, NewOptionExpandedTypes.codec(), opts) + } +} diff --git a/packages/protons/test/fixtures/peer.ts b/packages/protons/test/fixtures/peer.ts index afcda87..2f90ff0 100644 --- a/packages/protons/test/fixtures/peer.ts +++ b/packages/protons/test/fixtures/peer.ts @@ -55,17 +55,17 @@ export namespace Peer { if (opts.lengthDelimited !== false) { w.ldelim() } - }, (reader, length, opts = {}) => { + }, (r, length, opts = {}) => { const obj: any = { addresses: [], protocols: [], metadata: [] } - const end = length == null ? reader.len : reader.pos + length + const end = length == null ? r.len : r.pos + length - while (reader.pos < end) { - const tag = reader.uint32() + while (r.pos < end) { + const tag = r.uint32() switch (tag >>> 3) { case 1: { @@ -73,7 +73,7 @@ export namespace Peer { throw new MaxLengthError('Decode error - repeated field "addresses" had too many elements') } - obj.addresses.push(Address.codec().decode(reader, reader.uint32(), { + obj.addresses.push(Address.codec().decode(r, r.uint32(), { limits: opts.limits?.addresses$ })) break @@ -83,7 +83,7 @@ export namespace Peer { throw new MaxLengthError('Decode error - repeated field "protocols" had too many elements') } - obj.protocols.push(reader.string()) + obj.protocols.push(r.string()) break } case 3: { @@ -91,35 +91,35 @@ export namespace Peer { throw new MaxLengthError('Decode error - repeated field "metadata" had too many elements') } - obj.metadata.push(Metadata.codec().decode(reader, reader.uint32(), { + obj.metadata.push(Metadata.codec().decode(r, r.uint32(), { limits: opts.limits?.metadata$ })) break } case 4: { - obj.pubKey = reader.bytes() + obj.pubKey = r.bytes() break } case 5: { - obj.peerRecordEnvelope = reader.bytes() + obj.peerRecordEnvelope = r.bytes() break } default: { - reader.skipType(tag & 7) + r.skipType(tag & 7) break } } } return obj - }, function * (reader, length, prefix, opts = {}) { + }, function * (r, length, prefix, opts = {}) { const obj = { addresses: 0, protocols: 0, metadata: 0 } - const end = length == null ? reader.len : reader.pos + length + const end = length == null ? r.len : r.pos + length if (prefix !== '.') { yield { @@ -129,8 +129,8 @@ export namespace Peer { } } - while (reader.pos < end) { - const tag = reader.uint32() + while (r.pos < end) { + const tag = r.uint32() switch (tag >>> 3) { case 1: { @@ -138,7 +138,7 @@ export namespace Peer { throw new MaxLengthError('Streaming decode error - repeated field "addresses" had too many elements') } - for (const evt of Address.codec().stream(reader, reader.uint32(), `${prefix}addresses[].`, { + for (const evt of Address.codec().stream(r, r.uint32(), `${prefix}addresses[].`, { limits: opts.limits?.addresses$ })) { yield { @@ -159,7 +159,7 @@ export namespace Peer { yield { field: `${prefix}protocols[]`, index: obj.protocols, - value: reader.string() + value: r.string() } obj.protocols++ @@ -171,7 +171,7 @@ export namespace Peer { throw new MaxLengthError('Streaming decode error - repeated field "metadata" had too many elements') } - for (const evt of Metadata.codec().stream(reader, reader.uint32(), `${prefix}metadata[].`, { + for (const evt of Metadata.codec().stream(r, r.uint32(), `${prefix}metadata[].`, { limits: opts.limits?.metadata$ })) { yield { @@ -187,19 +187,19 @@ export namespace Peer { case 4: { yield { field: `${prefix}pubKey`, - value: reader.bytes() + value: r.bytes() } break } case 5: { yield { field: `${prefix}peerRecordEnvelope`, - value: reader.bytes() + value: r.bytes() } break } default: { - reader.skipType(tag & 7) + r.skipType(tag & 7) break } } @@ -327,35 +327,35 @@ export namespace Address { if (opts.lengthDelimited !== false) { w.ldelim() } - }, (reader, length, opts = {}) => { + }, (r, length, opts = {}) => { const obj: any = { multiaddr: uint8ArrayAlloc(0) } - const end = length == null ? reader.len : reader.pos + length + const end = length == null ? r.len : r.pos + length - while (reader.pos < end) { - const tag = reader.uint32() + while (r.pos < end) { + const tag = r.uint32() switch (tag >>> 3) { case 1: { - obj.multiaddr = reader.bytes() + obj.multiaddr = r.bytes() break } case 2: { - obj.isCertified = reader.bool() + obj.isCertified = r.bool() break } default: { - reader.skipType(tag & 7) + r.skipType(tag & 7) break } } } return obj - }, function * (reader, length, prefix, opts = {}) { - const end = length == null ? reader.len : reader.pos + length + }, function * (r, length, prefix, opts = {}) { + const end = length == null ? r.len : r.pos + length if (prefix !== '.') { yield { @@ -365,26 +365,26 @@ export namespace Address { } } - while (reader.pos < end) { - const tag = reader.uint32() + while (r.pos < end) { + const tag = r.uint32() switch (tag >>> 3) { case 1: { yield { field: `${prefix}multiaddr`, - value: reader.bytes() + value: r.bytes() } break } case 2: { yield { field: `${prefix}isCertified`, - value: reader.bool() + value: r.bool() } break } default: { - reader.skipType(tag & 7) + r.skipType(tag & 7) break } } @@ -454,36 +454,36 @@ export namespace Metadata { if (opts.lengthDelimited !== false) { w.ldelim() } - }, (reader, length, opts = {}) => { + }, (r, length, opts = {}) => { const obj: any = { key: '', value: uint8ArrayAlloc(0) } - const end = length == null ? reader.len : reader.pos + length + const end = length == null ? r.len : r.pos + length - while (reader.pos < end) { - const tag = reader.uint32() + while (r.pos < end) { + const tag = r.uint32() switch (tag >>> 3) { case 1: { - obj.key = reader.string() + obj.key = r.string() break } case 2: { - obj.value = reader.bytes() + obj.value = r.bytes() break } default: { - reader.skipType(tag & 7) + r.skipType(tag & 7) break } } } return obj - }, function * (reader, length, prefix, opts = {}) { - const end = length == null ? reader.len : reader.pos + length + }, function * (r, length, prefix, opts = {}) { + const end = length == null ? r.len : r.pos + length if (prefix !== '.') { yield { @@ -493,26 +493,26 @@ export namespace Metadata { } } - while (reader.pos < end) { - const tag = reader.uint32() + while (r.pos < end) { + const tag = r.uint32() switch (tag >>> 3) { case 1: { yield { field: `${prefix}key`, - value: reader.string() + value: r.string() } break } case 2: { yield { field: `${prefix}value`, - value: reader.bytes() + value: r.bytes() } break } default: { - reader.skipType(tag & 7) + r.skipType(tag & 7) break } } diff --git a/packages/protons/test/fixtures/proto2.ts b/packages/protons/test/fixtures/proto2.ts index 78580f2..668c3f2 100644 --- a/packages/protons/test/fixtures/proto2.ts +++ b/packages/protons/test/fixtures/proto2.ts @@ -24,31 +24,31 @@ export namespace MessageWithRequired { if (opts.lengthDelimited !== false) { w.ldelim() } - }, (reader, length, opts = {}) => { + }, (r, length, opts = {}) => { const obj: any = { scalarField: 0 } - const end = length == null ? reader.len : reader.pos + length + const end = length == null ? r.len : r.pos + length - while (reader.pos < end) { - const tag = reader.uint32() + while (r.pos < end) { + const tag = r.uint32() switch (tag >>> 3) { case 1: { - obj.scalarField = reader.int32() + obj.scalarField = r.int32() break } default: { - reader.skipType(tag & 7) + r.skipType(tag & 7) break } } } return obj - }, function * (reader, length, prefix, opts = {}) { - const end = length == null ? reader.len : reader.pos + length + }, function * (r, length, prefix, opts = {}) { + const end = length == null ? r.len : r.pos + length if (prefix !== '.') { yield { @@ -58,19 +58,19 @@ export namespace MessageWithRequired { } } - while (reader.pos < end) { - const tag = reader.uint32() + while (r.pos < end) { + const tag = r.uint32() switch (tag >>> 3) { case 1: { yield { field: `${prefix}scalarField`, - value: reader.int32() + value: r.int32() } break } default: { - reader.skipType(tag & 7) + r.skipType(tag & 7) break } } diff --git a/packages/protons/test/fixtures/protons-options.ts b/packages/protons/test/fixtures/protons-options.ts index 462fc4b..036b80c 100644 --- a/packages/protons/test/fixtures/protons-options.ts +++ b/packages/protons/test/fixtures/protons-options.ts @@ -26,15 +26,15 @@ export namespace MessageWithSizeLimitedRepeatedField { if (opts.lengthDelimited !== false) { w.ldelim() } - }, (reader, length, opts = {}) => { + }, (r, length, opts = {}) => { const obj: any = { repeatedField: [] } - const end = length == null ? reader.len : reader.pos + length + const end = length == null ? r.len : r.pos + length - while (reader.pos < end) { - const tag = reader.uint32() + while (r.pos < end) { + const tag = r.uint32() switch (tag >>> 3) { case 1: { @@ -46,23 +46,23 @@ export namespace MessageWithSizeLimitedRepeatedField { throw new MaxLengthError('Decode error - repeated field "repeatedField" had too many elements') } - obj.repeatedField.push(reader.string()) + obj.repeatedField.push(r.string()) break } default: { - reader.skipType(tag & 7) + r.skipType(tag & 7) break } } } return obj - }, function * (reader, length, prefix, opts = {}) { + }, function * (r, length, prefix, opts = {}) { const obj = { repeatedField: 1 } - const end = length == null ? reader.len : reader.pos + length + const end = length == null ? r.len : r.pos + length if (prefix !== '.') { yield { @@ -72,8 +72,8 @@ export namespace MessageWithSizeLimitedRepeatedField { } } - while (reader.pos < end) { - const tag = reader.uint32() + while (r.pos < end) { + const tag = r.uint32() switch (tag >>> 3) { case 1: { @@ -88,7 +88,7 @@ export namespace MessageWithSizeLimitedRepeatedField { yield { field: `${prefix}repeatedField[]`, index: obj.repeatedField, - value: reader.string() + value: r.string() } obj.repeatedField++ @@ -96,7 +96,7 @@ export namespace MessageWithSizeLimitedRepeatedField { break } default: { - reader.skipType(tag & 7) + r.skipType(tag & 7) break } } @@ -167,36 +167,36 @@ export namespace MessageWithSizeLimitedMap { if (opts.lengthDelimited !== false) { w.ldelim() } - }, (reader, length, opts = {}) => { + }, (r, length, opts = {}) => { const obj: any = { key: '', value: '' } - const end = length == null ? reader.len : reader.pos + length + const end = length == null ? r.len : r.pos + length - while (reader.pos < end) { - const tag = reader.uint32() + while (r.pos < end) { + const tag = r.uint32() switch (tag >>> 3) { case 1: { - obj.key = reader.string() + obj.key = r.string() break } case 2: { - obj.value = reader.string() + obj.value = r.string() break } default: { - reader.skipType(tag & 7) + r.skipType(tag & 7) break } } } return obj - }, function * (reader, length, prefix, opts = {}) { - const end = length == null ? reader.len : reader.pos + length + }, function * (r, length, prefix, opts = {}) { + const end = length == null ? r.len : r.pos + length if (prefix !== '.') { yield { @@ -206,26 +206,26 @@ export namespace MessageWithSizeLimitedMap { } } - while (reader.pos < end) { - const tag = reader.uint32() + while (r.pos < end) { + const tag = r.uint32() switch (tag >>> 3) { case 1: { yield { field: `${prefix}key`, - value: reader.string() + value: r.string() } break } case 2: { yield { field: `${prefix}value`, - value: reader.string() + value: r.string() } break } default: { - reader.skipType(tag & 7) + r.skipType(tag & 7) break } } @@ -286,15 +286,15 @@ export namespace MessageWithSizeLimitedMap { if (opts.lengthDelimited !== false) { w.ldelim() } - }, (reader, length, opts = {}) => { + }, (r, length, opts = {}) => { const obj: any = { mapField: new Map() } - const end = length == null ? reader.len : reader.pos + length + const end = length == null ? r.len : r.pos + length - while (reader.pos < end) { - const tag = reader.uint32() + while (r.pos < end) { + const tag = r.uint32() switch (tag >>> 3) { case 1: { @@ -306,7 +306,7 @@ export namespace MessageWithSizeLimitedMap { throw new MaxSizeError('Decode error - map field "mapField" had too many elements') } - const entry = MessageWithSizeLimitedMap.MessageWithSizeLimitedMap$mapFieldEntry.codec().decode(reader, reader.uint32(), { + const entry = MessageWithSizeLimitedMap.MessageWithSizeLimitedMap$mapFieldEntry.codec().decode(r, r.uint32(), { limits: { value: opts.limits?.mapField$value } @@ -315,19 +315,19 @@ export namespace MessageWithSizeLimitedMap { break } default: { - reader.skipType(tag & 7) + r.skipType(tag & 7) break } } } return obj - }, function * (reader, length, prefix, opts = {}) { + }, function * (r, length, prefix, opts = {}) { const obj = { mapField: 1 } - const end = length == null ? reader.len : reader.pos + length + const end = length == null ? r.len : r.pos + length if (prefix !== '.') { yield { @@ -337,8 +337,8 @@ export namespace MessageWithSizeLimitedMap { } } - while (reader.pos < end) { - const tag = reader.uint32() + while (r.pos < end) { + const tag = r.uint32() switch (tag >>> 3) { case 1: { @@ -350,7 +350,7 @@ export namespace MessageWithSizeLimitedMap { throw new MaxLengthError('Decode error - repeated field "mapField" had too many elements') } - yield * MessageWithSizeLimitedMap.MessageWithSizeLimitedMap$mapFieldEntry.codec().stream(reader, reader.uint32(), `${prefix}mapField{}.`, { + yield * MessageWithSizeLimitedMap.MessageWithSizeLimitedMap$mapFieldEntry.codec().stream(r, r.uint32(), `${prefix}mapField{}.`, { limits: { value: opts.limits?.mapField$value } @@ -361,7 +361,7 @@ export namespace MessageWithSizeLimitedMap { break } default: { - reader.skipType(tag & 7) + r.skipType(tag & 7) break } } diff --git a/packages/protons/test/fixtures/repeated.ts b/packages/protons/test/fixtures/repeated.ts index 3fca755..0516b39 100644 --- a/packages/protons/test/fixtures/repeated.ts +++ b/packages/protons/test/fixtures/repeated.ts @@ -1,4 +1,4 @@ -import { decodeMessage, encodeMessage, MaxLengthError, message, streamMessage } from 'protons-runtime' +import { decodeMessage, encodeMessage, MaxLengthError, message, reader, streamMessage } from 'protons-runtime' import type { Codec, DecodeOptions } from 'protons-runtime' import type { Uint8ArrayList } from 'uint8arraylist' @@ -32,15 +32,15 @@ export namespace SubSubMessage { if (opts.lengthDelimited !== false) { w.ldelim() } - }, (reader, length, opts = {}) => { + }, (r, length, opts = {}) => { const obj: any = { foo: [] } - const end = length == null ? reader.len : reader.pos + length + const end = length == null ? r.len : r.pos + length - while (reader.pos < end) { - const tag = reader.uint32() + while (r.pos < end) { + const tag = r.uint32() switch (tag >>> 3) { case 1: { @@ -48,27 +48,27 @@ export namespace SubSubMessage { throw new MaxLengthError('Decode error - repeated field "foo" had too many elements') } - obj.foo.push(reader.string()) + obj.foo.push(r.string()) break } case 2: { - obj.nonRepeating = reader.uint32() + obj.nonRepeating = r.uint32() break } default: { - reader.skipType(tag & 7) + r.skipType(tag & 7) break } } } return obj - }, function * (reader, length, prefix, opts = {}) { + }, function * (r, length, prefix, opts = {}) { const obj = { foo: 0 } - const end = length == null ? reader.len : reader.pos + length + const end = length == null ? r.len : r.pos + length if (prefix !== '.') { yield { @@ -78,8 +78,8 @@ export namespace SubSubMessage { } } - while (reader.pos < end) { - const tag = reader.uint32() + while (r.pos < end) { + const tag = r.uint32() switch (tag >>> 3) { case 1: { @@ -90,7 +90,7 @@ export namespace SubSubMessage { yield { field: `${prefix}foo[]`, index: obj.foo, - value: reader.string() + value: r.string() } obj.foo++ @@ -100,12 +100,12 @@ export namespace SubSubMessage { case 2: { yield { field: `${prefix}nonRepeating`, - value: reader.uint32() + value: r.uint32() } break } default: { - reader.skipType(tag & 7) + r.skipType(tag & 7) break } } @@ -192,16 +192,16 @@ export namespace SubMessage { if (opts.lengthDelimited !== false) { w.ldelim() } - }, (reader, length, opts = {}) => { + }, (r, length, opts = {}) => { const obj: any = { foo: [], messages: [] } - const end = length == null ? reader.len : reader.pos + length + const end = length == null ? r.len : r.pos + length - while (reader.pos < end) { - const tag = reader.uint32() + while (r.pos < end) { + const tag = r.uint32() switch (tag >>> 3) { case 1: { @@ -209,15 +209,15 @@ export namespace SubMessage { throw new MaxLengthError('Decode error - repeated field "foo" had too many elements') } - obj.foo.push(reader.string()) + obj.foo.push(r.string()) break } case 2: { - obj.nonRepeating = reader.uint32() + obj.nonRepeating = r.uint32() break } case 3: { - obj.message = SubSubMessage.codec().decode(reader, reader.uint32(), { + obj.message = SubSubMessage.codec().decode(r, r.uint32(), { limits: opts.limits?.message }) break @@ -227,26 +227,26 @@ export namespace SubMessage { throw new MaxLengthError('Decode error - repeated field "messages" had too many elements') } - obj.messages.push(SubSubMessage.codec().decode(reader, reader.uint32(), { + obj.messages.push(SubSubMessage.codec().decode(r, r.uint32(), { limits: opts.limits?.messages$ })) break } default: { - reader.skipType(tag & 7) + r.skipType(tag & 7) break } } } return obj - }, function * (reader, length, prefix, opts = {}) { + }, function * (r, length, prefix, opts = {}) { const obj = { foo: 0, messages: 0 } - const end = length == null ? reader.len : reader.pos + length + const end = length == null ? r.len : r.pos + length if (prefix !== '.') { yield { @@ -256,8 +256,8 @@ export namespace SubMessage { } } - while (reader.pos < end) { - const tag = reader.uint32() + while (r.pos < end) { + const tag = r.uint32() switch (tag >>> 3) { case 1: { @@ -268,7 +268,7 @@ export namespace SubMessage { yield { field: `${prefix}foo[]`, index: obj.foo, - value: reader.string() + value: r.string() } obj.foo++ @@ -278,12 +278,12 @@ export namespace SubMessage { case 2: { yield { field: `${prefix}nonRepeating`, - value: reader.uint32() + value: r.uint32() } break } case 3: { - yield * SubSubMessage.codec().stream(reader, reader.uint32(), `${prefix}message.`, { + yield * SubSubMessage.codec().stream(r, r.uint32(), `${prefix}message.`, { limits: opts.limits?.message }) @@ -294,7 +294,7 @@ export namespace SubMessage { throw new MaxLengthError('Streaming decode error - repeated field "messages" had too many elements') } - for (const evt of SubSubMessage.codec().stream(reader, reader.uint32(), `${prefix}messages[].`, { + for (const evt of SubSubMessage.codec().stream(r, r.uint32(), `${prefix}messages[].`, { limits: opts.limits?.messages$ })) { yield { @@ -308,7 +308,7 @@ export namespace SubMessage { break } default: { - reader.skipType(tag & 7) + r.skipType(tag & 7) break } } @@ -417,17 +417,25 @@ export namespace RepeatedTypes { } if (obj.number != null && obj.number.length > 0) { + w.uint32(10) + w.fork() + for (const value of obj.number) { - w.uint32(8) w.uint32(value) } + + w.ldelim() } if (obj.limitedNumber != null && obj.limitedNumber.length > 0) { + w.uint32(18) + w.fork() + for (const value of obj.limitedNumber) { - w.uint32(16) w.uint32(value) } + + w.ldelim() } if (obj.messages != null && obj.messages.length > 0) { @@ -450,37 +458,49 @@ export namespace RepeatedTypes { if (opts.lengthDelimited !== false) { w.ldelim() } - }, (reader, length, opts = {}) => { + }, (r, length, opts = {}) => { const obj: any = { number: [], limitedNumber: [], messages: [] } - const end = length == null ? reader.len : reader.pos + length + const end = length == null ? r.len : r.pos + length - while (reader.pos < end) { - const tag = reader.uint32() + while (r.pos < end) { + const tag = r.uint32() switch (tag >>> 3) { case 1: { - if (opts.limits?.number != null && obj.number.length === opts.limits.number) { - throw new MaxLengthError('Decode error - repeated field "number" had too many elements') + const b = r.bytes() + const r2 = reader(b) + + while (r2.pos < r2.len) { + if (opts.limits?.number != null && obj.number.length === opts.limits.number) { + throw new MaxLengthError('Decode error - repeated field "number" had too many elements') + } + + obj.number.push(r2.uint32()) } - obj.number.push(reader.uint32()) break } case 2: { - if (opts.limits?.limitedNumber != null && obj.limitedNumber.length === opts.limits.limitedNumber) { - throw new MaxLengthError('Decode error - repeated field "limitedNumber" had too many elements') - } + const b = r.bytes() + const r2 = reader(b) + + while (r2.pos < r2.len) { + if (opts.limits?.limitedNumber != null && obj.limitedNumber.length === opts.limits.limitedNumber) { + throw new MaxLengthError('Decode error - repeated field "limitedNumber" had too many elements') + } + + if (obj.limitedNumber.length === 1) { + throw new MaxLengthError('Decode error - repeated field "limitedNumber" had too many elements') + } - if (obj.limitedNumber.length === 1) { - throw new MaxLengthError('Decode error - repeated field "limitedNumber" had too many elements') + obj.limitedNumber.push(r2.uint32()) } - obj.limitedNumber.push(reader.uint32()) break } case 3: { @@ -488,37 +508,37 @@ export namespace RepeatedTypes { throw new MaxLengthError('Decode error - repeated field "messages" had too many elements') } - obj.messages.push(SubMessage.codec().decode(reader, reader.uint32(), { + obj.messages.push(SubMessage.codec().decode(r, r.uint32(), { limits: opts.limits?.messages$ })) break } case 4: { - obj.message = SubMessage.codec().decode(reader, reader.uint32(), { + obj.message = SubMessage.codec().decode(r, r.uint32(), { limits: opts.limits?.message }) break } case 5: { - obj.nonRepeating = reader.uint32() + obj.nonRepeating = r.uint32() break } default: { - reader.skipType(tag & 7) + r.skipType(tag & 7) break } } } return obj - }, function * (reader, length, prefix, opts = {}) { + }, function * (r, length, prefix, opts = {}) { const obj = { number: 0, limitedNumber: 1, messages: 0 } - const end = length == null ? reader.len : reader.pos + length + const end = length == null ? r.len : r.pos + length if (prefix !== '.') { yield { @@ -528,41 +548,51 @@ export namespace RepeatedTypes { } } - while (reader.pos < end) { - const tag = reader.uint32() + while (r.pos < end) { + const tag = r.uint32() switch (tag >>> 3) { case 1: { - if (opts.limits?.number != null && obj.number === opts.limits.number) { - throw new MaxLengthError('Streaming decode error - repeated field "number" had too many elements') - } + const b = r.bytes() + const r2 = reader(b) - yield { - field: `${prefix}number[]`, - index: obj.number, - value: reader.uint32() - } + while (r2.pos < r2.len) { + if (opts.limits?.number != null && obj.number === opts.limits.number) { + throw new MaxLengthError('Streaming decode error - repeated field "number" had too many elements') + } - obj.number++ + yield { + field: `${prefix}number[]`, + index: obj.number, + value: r2.uint32() + } + + obj.number++ + } break } case 2: { - if (opts.limits?.limitedNumber != null && obj.limitedNumber === opts.limits.limitedNumber) { - throw new MaxLengthError('Streaming decode error - repeated field "limitedNumber" had too many elements') - } + const b = r.bytes() + const r2 = reader(b) - if (obj.limitedNumber === 1) { - throw new MaxLengthError('Streaming decode error - repeated field "limitedNumber" had too many elements') - } + while (r2.pos < r2.len) { + if (opts.limits?.limitedNumber != null && obj.limitedNumber === opts.limits.limitedNumber) { + throw new MaxLengthError('Streaming decode error - repeated field "limitedNumber" had too many elements') + } - yield { - field: `${prefix}limitedNumber[]`, - index: obj.limitedNumber, - value: reader.uint32() - } + if (obj.limitedNumber === 1) { + throw new MaxLengthError('Streaming decode error - repeated field "limitedNumber" had too many elements') + } - obj.limitedNumber++ + yield { + field: `${prefix}limitedNumber[]`, + index: obj.limitedNumber, + value: r2.uint32() + } + + obj.limitedNumber++ + } break } @@ -571,7 +601,7 @@ export namespace RepeatedTypes { throw new MaxLengthError('Streaming decode error - repeated field "messages" had too many elements') } - for (const evt of SubMessage.codec().stream(reader, reader.uint32(), `${prefix}messages[].`, { + for (const evt of SubMessage.codec().stream(r, r.uint32(), `${prefix}messages[].`, { limits: opts.limits?.messages$ })) { yield { @@ -585,7 +615,7 @@ export namespace RepeatedTypes { break } case 4: { - yield * SubMessage.codec().stream(reader, reader.uint32(), `${prefix}message.`, { + yield * SubMessage.codec().stream(r, r.uint32(), `${prefix}message.`, { limits: opts.limits?.message }) @@ -594,12 +624,12 @@ export namespace RepeatedTypes { case 5: { yield { field: `${prefix}nonRepeating`, - value: reader.uint32() + value: r.uint32() } break } default: { - reader.skipType(tag & 7) + r.skipType(tag & 7) break } } diff --git a/packages/protons/test/fixtures/singular.ts b/packages/protons/test/fixtures/singular.ts index d9f5c8c..834400e 100644 --- a/packages/protons/test/fixtures/singular.ts +++ b/packages/protons/test/fixtures/singular.ts @@ -49,36 +49,36 @@ export namespace SingularSubMessage { if (opts.lengthDelimited !== false) { w.ldelim() } - }, (reader, length, opts = {}) => { + }, (r, length, opts = {}) => { const obj: any = { foo: '', bar: 0 } - const end = length == null ? reader.len : reader.pos + length + const end = length == null ? r.len : r.pos + length - while (reader.pos < end) { - const tag = reader.uint32() + while (r.pos < end) { + const tag = r.uint32() switch (tag >>> 3) { case 1: { - obj.foo = reader.string() + obj.foo = r.string() break } case 2: { - obj.bar = reader.int32() + obj.bar = r.int32() break } default: { - reader.skipType(tag & 7) + r.skipType(tag & 7) break } } } return obj - }, function * (reader, length, prefix, opts = {}) { - const end = length == null ? reader.len : reader.pos + length + }, function * (r, length, prefix, opts = {}) { + const end = length == null ? r.len : r.pos + length if (prefix !== '.') { yield { @@ -88,26 +88,26 @@ export namespace SingularSubMessage { } } - while (reader.pos < end) { - const tag = reader.uint32() + while (r.pos < end) { + const tag = r.uint32() switch (tag >>> 3) { case 1: { yield { field: `${prefix}foo`, - value: reader.string() + value: r.string() } break } case 2: { yield { field: `${prefix}bar`, - value: reader.int32() + value: r.int32() } break } default: { - reader.skipType(tag & 7) + r.skipType(tag & 7) break } } @@ -267,7 +267,7 @@ export namespace Singular { if (opts.lengthDelimited !== false) { w.ldelim() } - }, (reader, length, opts = {}) => { + }, (r, length, opts = {}) => { const obj: any = { double: 0, float: 0, @@ -287,92 +287,92 @@ export namespace Singular { enum: SingularEnum.NO_VALUE } - const end = length == null ? reader.len : reader.pos + length + const end = length == null ? r.len : r.pos + length - while (reader.pos < end) { - const tag = reader.uint32() + while (r.pos < end) { + const tag = r.uint32() switch (tag >>> 3) { case 1: { - obj.double = reader.double() + obj.double = r.double() break } case 2: { - obj.float = reader.float() + obj.float = r.float() break } case 3: { - obj.int32 = reader.int32() + obj.int32 = r.int32() break } case 4: { - obj.int64 = reader.int64() + obj.int64 = r.int64() break } case 5: { - obj.uint32 = reader.uint32() + obj.uint32 = r.uint32() break } case 6: { - obj.uint64 = reader.uint64() + obj.uint64 = r.uint64() break } case 7: { - obj.sint32 = reader.sint32() + obj.sint32 = r.sint32() break } case 8: { - obj.sint64 = reader.sint64() + obj.sint64 = r.sint64() break } case 9: { - obj.fixed32 = reader.fixed32() + obj.fixed32 = r.fixed32() break } case 10: { - obj.fixed64 = reader.fixed64() + obj.fixed64 = r.fixed64() break } case 11: { - obj.sfixed32 = reader.sfixed32() + obj.sfixed32 = r.sfixed32() break } case 12: { - obj.sfixed64 = reader.sfixed64() + obj.sfixed64 = r.sfixed64() break } case 13: { - obj.bool = reader.bool() + obj.bool = r.bool() break } case 14: { - obj.string = reader.string() + obj.string = r.string() break } case 15: { - obj.bytes = reader.bytes() + obj.bytes = r.bytes() break } case 16: { - obj.enum = SingularEnum.codec().decode(reader) + obj.enum = SingularEnum.codec().decode(r) break } case 17: { - obj.subMessage = SingularSubMessage.codec().decode(reader, reader.uint32(), { + obj.subMessage = SingularSubMessage.codec().decode(r, r.uint32(), { limits: opts.limits?.subMessage }) break } default: { - reader.skipType(tag & 7) + r.skipType(tag & 7) break } } } return obj - }, function * (reader, length, prefix, opts = {}) { - const end = length == null ? reader.len : reader.pos + length + }, function * (r, length, prefix, opts = {}) { + const end = length == null ? r.len : r.pos + length if (prefix !== '.') { yield { @@ -382,131 +382,131 @@ export namespace Singular { } } - while (reader.pos < end) { - const tag = reader.uint32() + while (r.pos < end) { + const tag = r.uint32() switch (tag >>> 3) { case 1: { yield { field: `${prefix}double`, - value: reader.double() + value: r.double() } break } case 2: { yield { field: `${prefix}float`, - value: reader.float() + value: r.float() } break } case 3: { yield { field: `${prefix}int32`, - value: reader.int32() + value: r.int32() } break } case 4: { yield { field: `${prefix}int64`, - value: reader.int64() + value: r.int64() } break } case 5: { yield { field: `${prefix}uint32`, - value: reader.uint32() + value: r.uint32() } break } case 6: { yield { field: `${prefix}uint64`, - value: reader.uint64() + value: r.uint64() } break } case 7: { yield { field: `${prefix}sint32`, - value: reader.sint32() + value: r.sint32() } break } case 8: { yield { field: `${prefix}sint64`, - value: reader.sint64() + value: r.sint64() } break } case 9: { yield { field: `${prefix}fixed32`, - value: reader.fixed32() + value: r.fixed32() } break } case 10: { yield { field: `${prefix}fixed64`, - value: reader.fixed64() + value: r.fixed64() } break } case 11: { yield { field: `${prefix}sfixed32`, - value: reader.sfixed32() + value: r.sfixed32() } break } case 12: { yield { field: `${prefix}sfixed64`, - value: reader.sfixed64() + value: r.sfixed64() } break } case 13: { yield { field: `${prefix}bool`, - value: reader.bool() + value: r.bool() } break } case 14: { yield { field: `${prefix}string`, - value: reader.string() + value: r.string() } break } case 15: { yield { field: `${prefix}bytes`, - value: reader.bytes() + value: r.bytes() } break } case 16: { yield { field: `${prefix}enum`, - value: SingularEnum.codec().decode(reader) + value: SingularEnum.codec().decode(r) } break } case 17: { - yield * SingularSubMessage.codec().stream(reader, reader.uint32(), `${prefix}subMessage.`, { + yield * SingularSubMessage.codec().stream(r, r.uint32(), `${prefix}subMessage.`, { limits: opts.limits?.subMessage }) break } default: { - reader.skipType(tag & 7) + r.skipType(tag & 7) break } } diff --git a/packages/protons/test/fixtures/streaming.ts b/packages/protons/test/fixtures/streaming.ts index 8e8f960..62a5fe6 100644 --- a/packages/protons/test/fixtures/streaming.ts +++ b/packages/protons/test/fixtures/streaming.ts @@ -38,23 +38,23 @@ export namespace MessageWithArrayField { if (opts.lengthDelimited !== false) { w.ldelim() } - }, (reader, length, opts = {}) => { + }, (r, length, opts = {}) => { const obj: any = { arr: [] } - const end = length == null ? reader.len : reader.pos + length + const end = length == null ? r.len : r.pos + length - while (reader.pos < end) { - const tag = reader.uint32() + while (r.pos < end) { + const tag = r.uint32() switch (tag >>> 3) { case 1: { - obj.field1 = reader.bool() + obj.field1 = r.bool() break } case 2: { - obj.field2 = reader.uint32() + obj.field2 = r.uint32() break } case 3: { @@ -62,23 +62,23 @@ export namespace MessageWithArrayField { throw new MaxLengthError('Decode error - repeated field "arr" had too many elements') } - obj.arr.push(reader.string()) + obj.arr.push(r.string()) break } default: { - reader.skipType(tag & 7) + r.skipType(tag & 7) break } } } return obj - }, function * (reader, length, prefix, opts = {}) { + }, function * (r, length, prefix, opts = {}) { const obj = { arr: 0 } - const end = length == null ? reader.len : reader.pos + length + const end = length == null ? r.len : r.pos + length if (prefix !== '.') { yield { @@ -88,21 +88,21 @@ export namespace MessageWithArrayField { } } - while (reader.pos < end) { - const tag = reader.uint32() + while (r.pos < end) { + const tag = r.uint32() switch (tag >>> 3) { case 1: { yield { field: `${prefix}field1`, - value: reader.bool() + value: r.bool() } break } case 2: { yield { field: `${prefix}field2`, - value: reader.uint32() + value: r.uint32() } break } @@ -114,7 +114,7 @@ export namespace MessageWithArrayField { yield { field: `${prefix}arr[]`, index: obj.arr, - value: reader.string() + value: r.string() } obj.arr++ @@ -122,7 +122,7 @@ export namespace MessageWithArrayField { break } default: { - reader.skipType(tag & 7) + r.skipType(tag & 7) break } } @@ -192,31 +192,31 @@ export namespace NestedMessage { if (opts.lengthDelimited !== false) { w.ldelim() } - }, (reader, length, opts = {}) => { + }, (r, length, opts = {}) => { const obj: any = { nestedValue: '' } - const end = length == null ? reader.len : reader.pos + length + const end = length == null ? r.len : r.pos + length - while (reader.pos < end) { - const tag = reader.uint32() + while (r.pos < end) { + const tag = r.uint32() switch (tag >>> 3) { case 1: { - obj.nestedValue = reader.string() + obj.nestedValue = r.string() break } default: { - reader.skipType(tag & 7) + r.skipType(tag & 7) break } } } return obj - }, function * (reader, length, prefix, opts = {}) { - const end = length == null ? reader.len : reader.pos + length + }, function * (r, length, prefix, opts = {}) { + const end = length == null ? r.len : r.pos + length if (prefix !== '.') { yield { @@ -226,19 +226,19 @@ export namespace NestedMessage { } } - while (reader.pos < end) { - const tag = reader.uint32() + while (r.pos < end) { + const tag = r.uint32() switch (tag >>> 3) { case 1: { yield { field: `${prefix}nestedValue`, - value: reader.string() + value: r.string() } break } default: { - reader.skipType(tag & 7) + r.skipType(tag & 7) break } } @@ -303,37 +303,37 @@ export namespace MessageWithNestedMessage { if (opts.lengthDelimited !== false) { w.ldelim() } - }, (reader, length, opts = {}) => { + }, (r, length, opts = {}) => { const obj: any = { field1: false } - const end = length == null ? reader.len : reader.pos + length + const end = length == null ? r.len : r.pos + length - while (reader.pos < end) { - const tag = reader.uint32() + while (r.pos < end) { + const tag = r.uint32() switch (tag >>> 3) { case 1: { - obj.field1 = reader.bool() + obj.field1 = r.bool() break } case 2: { - obj.nestedMessage = NestedMessage.codec().decode(reader, reader.uint32(), { + obj.nestedMessage = NestedMessage.codec().decode(r, r.uint32(), { limits: opts.limits?.nestedMessage }) break } default: { - reader.skipType(tag & 7) + r.skipType(tag & 7) break } } } return obj - }, function * (reader, length, prefix, opts = {}) { - const end = length == null ? reader.len : reader.pos + length + }, function * (r, length, prefix, opts = {}) { + const end = length == null ? r.len : r.pos + length if (prefix !== '.') { yield { @@ -343,26 +343,26 @@ export namespace MessageWithNestedMessage { } } - while (reader.pos < end) { - const tag = reader.uint32() + while (r.pos < end) { + const tag = r.uint32() switch (tag >>> 3) { case 1: { yield { field: `${prefix}field1`, - value: reader.bool() + value: r.bool() } break } case 2: { - yield * NestedMessage.codec().stream(reader, reader.uint32(), `${prefix}nestedMessage.`, { + yield * NestedMessage.codec().stream(r, r.uint32(), `${prefix}nestedMessage.`, { limits: opts.limits?.nestedMessage }) break } default: { - reader.skipType(tag & 7) + r.skipType(tag & 7) break } } @@ -442,37 +442,37 @@ export namespace MessageWithDeeplyNestedMessage { if (opts.lengthDelimited !== false) { w.ldelim() } - }, (reader, length, opts = {}) => { + }, (r, length, opts = {}) => { const obj: any = { field1: false } - const end = length == null ? reader.len : reader.pos + length + const end = length == null ? r.len : r.pos + length - while (reader.pos < end) { - const tag = reader.uint32() + while (r.pos < end) { + const tag = r.uint32() switch (tag >>> 3) { case 1: { - obj.field1 = reader.bool() + obj.field1 = r.bool() break } case 2: { - obj.nestedMessage = MessageWithNestedMessage.codec().decode(reader, reader.uint32(), { + obj.nestedMessage = MessageWithNestedMessage.codec().decode(r, r.uint32(), { limits: opts.limits?.nestedMessage }) break } default: { - reader.skipType(tag & 7) + r.skipType(tag & 7) break } } } return obj - }, function * (reader, length, prefix, opts = {}) { - const end = length == null ? reader.len : reader.pos + length + }, function * (r, length, prefix, opts = {}) { + const end = length == null ? r.len : r.pos + length if (prefix !== '.') { yield { @@ -482,26 +482,26 @@ export namespace MessageWithDeeplyNestedMessage { } } - while (reader.pos < end) { - const tag = reader.uint32() + while (r.pos < end) { + const tag = r.uint32() switch (tag >>> 3) { case 1: { yield { field: `${prefix}field1`, - value: reader.bool() + value: r.bool() } break } case 2: { - yield * MessageWithNestedMessage.codec().stream(reader, reader.uint32(), `${prefix}nestedMessage.`, { + yield * MessageWithNestedMessage.codec().stream(r, r.uint32(), `${prefix}nestedMessage.`, { limits: opts.limits?.nestedMessage }) break } default: { - reader.skipType(tag & 7) + r.skipType(tag & 7) break } } @@ -598,20 +598,20 @@ export namespace MessageWithRepeatedMessage { if (opts.lengthDelimited !== false) { w.ldelim() } - }, (reader, length, opts = {}) => { + }, (r, length, opts = {}) => { const obj: any = { field1: false, nestedMessages: [] } - const end = length == null ? reader.len : reader.pos + length + const end = length == null ? r.len : r.pos + length - while (reader.pos < end) { - const tag = reader.uint32() + while (r.pos < end) { + const tag = r.uint32() switch (tag >>> 3) { case 1: { - obj.field1 = reader.bool() + obj.field1 = r.bool() break } case 2: { @@ -619,25 +619,25 @@ export namespace MessageWithRepeatedMessage { throw new MaxLengthError('Decode error - repeated field "nestedMessages" had too many elements') } - obj.nestedMessages.push(NestedMessage.codec().decode(reader, reader.uint32(), { + obj.nestedMessages.push(NestedMessage.codec().decode(r, r.uint32(), { limits: opts.limits?.nestedMessages$ })) break } default: { - reader.skipType(tag & 7) + r.skipType(tag & 7) break } } } return obj - }, function * (reader, length, prefix, opts = {}) { + }, function * (r, length, prefix, opts = {}) { const obj = { nestedMessages: 0 } - const end = length == null ? reader.len : reader.pos + length + const end = length == null ? r.len : r.pos + length if (prefix !== '.') { yield { @@ -647,14 +647,14 @@ export namespace MessageWithRepeatedMessage { } } - while (reader.pos < end) { - const tag = reader.uint32() + while (r.pos < end) { + const tag = r.uint32() switch (tag >>> 3) { case 1: { yield { field: `${prefix}field1`, - value: reader.bool() + value: r.bool() } break } @@ -663,7 +663,7 @@ export namespace MessageWithRepeatedMessage { throw new MaxLengthError('Streaming decode error - repeated field "nestedMessages" had too many elements') } - for (const evt of NestedMessage.codec().stream(reader, reader.uint32(), `${prefix}nestedMessages[].`, { + for (const evt of NestedMessage.codec().stream(r, r.uint32(), `${prefix}nestedMessages[].`, { limits: opts.limits?.nestedMessages$ })) { yield { @@ -677,7 +677,7 @@ export namespace MessageWithRepeatedMessage { break } default: { - reader.skipType(tag & 7) + r.skipType(tag & 7) break } } @@ -768,37 +768,37 @@ export namespace MessageWithMapMessage { if (opts.lengthDelimited !== false) { w.ldelim() } - }, (reader, length, opts = {}) => { + }, (r, length, opts = {}) => { const obj: any = { key: '' } - const end = length == null ? reader.len : reader.pos + length + const end = length == null ? r.len : r.pos + length - while (reader.pos < end) { - const tag = reader.uint32() + while (r.pos < end) { + const tag = r.uint32() switch (tag >>> 3) { case 1: { - obj.key = reader.string() + obj.key = r.string() break } case 2: { - obj.value = NestedMessage.codec().decode(reader, reader.uint32(), { + obj.value = NestedMessage.codec().decode(r, r.uint32(), { limits: opts.limits?.value }) break } default: { - reader.skipType(tag & 7) + r.skipType(tag & 7) break } } } return obj - }, function * (reader, length, prefix, opts = {}) { - const end = length == null ? reader.len : reader.pos + length + }, function * (r, length, prefix, opts = {}) { + const end = length == null ? r.len : r.pos + length if (prefix !== '.') { yield { @@ -808,26 +808,26 @@ export namespace MessageWithMapMessage { } } - while (reader.pos < end) { - const tag = reader.uint32() + while (r.pos < end) { + const tag = r.uint32() switch (tag >>> 3) { case 1: { yield { field: `${prefix}key`, - value: reader.string() + value: r.string() } break } case 2: { - yield * NestedMessage.codec().stream(reader, reader.uint32(), `${prefix}value.`, { + yield * NestedMessage.codec().stream(r, r.uint32(), `${prefix}value.`, { limits: opts.limits?.value }) break } default: { - reader.skipType(tag & 7) + r.skipType(tag & 7) break } } @@ -903,20 +903,20 @@ export namespace MessageWithMapMessage { if (opts.lengthDelimited !== false) { w.ldelim() } - }, (reader, length, opts = {}) => { + }, (r, length, opts = {}) => { const obj: any = { field1: false, nestedMessages: new Map() } - const end = length == null ? reader.len : reader.pos + length + const end = length == null ? r.len : r.pos + length - while (reader.pos < end) { - const tag = reader.uint32() + while (r.pos < end) { + const tag = r.uint32() switch (tag >>> 3) { case 1: { - obj.field1 = reader.bool() + obj.field1 = r.bool() break } case 2: { @@ -924,7 +924,7 @@ export namespace MessageWithMapMessage { throw new MaxSizeError('Decode error - map field "nestedMessages" had too many elements') } - const entry = MessageWithMapMessage.MessageWithMapMessage$nestedMessagesEntry.codec().decode(reader, reader.uint32(), { + const entry = MessageWithMapMessage.MessageWithMapMessage$nestedMessagesEntry.codec().decode(r, r.uint32(), { limits: { value: opts.limits?.nestedMessages$value } @@ -933,19 +933,19 @@ export namespace MessageWithMapMessage { break } default: { - reader.skipType(tag & 7) + r.skipType(tag & 7) break } } } return obj - }, function * (reader, length, prefix, opts = {}) { + }, function * (r, length, prefix, opts = {}) { const obj = { nestedMessages: 0 } - const end = length == null ? reader.len : reader.pos + length + const end = length == null ? r.len : r.pos + length if (prefix !== '.') { yield { @@ -955,14 +955,14 @@ export namespace MessageWithMapMessage { } } - while (reader.pos < end) { - const tag = reader.uint32() + while (r.pos < end) { + const tag = r.uint32() switch (tag >>> 3) { case 1: { yield { field: `${prefix}field1`, - value: reader.bool() + value: r.bool() } break } @@ -971,7 +971,7 @@ export namespace MessageWithMapMessage { throw new MaxLengthError('Decode error - map field "nestedMessages" had too many elements') } - yield * MessageWithMapMessage.MessageWithMapMessage$nestedMessagesEntry.codec().stream(reader, reader.uint32(), `${prefix}nestedMessages{}.`, { + yield * MessageWithMapMessage.MessageWithMapMessage$nestedMessagesEntry.codec().stream(r, r.uint32(), `${prefix}nestedMessages{}.`, { limits: { value: opts.limits?.nestedMessages$value } @@ -982,7 +982,7 @@ export namespace MessageWithMapMessage { break } default: { - reader.skipType(tag & 7) + r.skipType(tag & 7) break } } @@ -1073,36 +1073,36 @@ export namespace MessageWithPrimitiveMap { if (opts.lengthDelimited !== false) { w.ldelim() } - }, (reader, length, opts = {}) => { + }, (r, length, opts = {}) => { const obj: any = { key: '', value: '' } - const end = length == null ? reader.len : reader.pos + length + const end = length == null ? r.len : r.pos + length - while (reader.pos < end) { - const tag = reader.uint32() + while (r.pos < end) { + const tag = r.uint32() switch (tag >>> 3) { case 1: { - obj.key = reader.string() + obj.key = r.string() break } case 2: { - obj.value = reader.string() + obj.value = r.string() break } default: { - reader.skipType(tag & 7) + r.skipType(tag & 7) break } } } return obj - }, function * (reader, length, prefix, opts = {}) { - const end = length == null ? reader.len : reader.pos + length + }, function * (r, length, prefix, opts = {}) { + const end = length == null ? r.len : r.pos + length if (prefix !== '.') { yield { @@ -1112,26 +1112,26 @@ export namespace MessageWithPrimitiveMap { } } - while (reader.pos < end) { - const tag = reader.uint32() + while (r.pos < end) { + const tag = r.uint32() switch (tag >>> 3) { case 1: { yield { field: `${prefix}key`, - value: reader.string() + value: r.string() } break } case 2: { yield { field: `${prefix}value`, - value: reader.string() + value: r.string() } break } default: { - reader.skipType(tag & 7) + r.skipType(tag & 7) break } } @@ -1197,20 +1197,20 @@ export namespace MessageWithPrimitiveMap { if (opts.lengthDelimited !== false) { w.ldelim() } - }, (reader, length, opts = {}) => { + }, (r, length, opts = {}) => { const obj: any = { field1: false, nestedStrings: new Map() } - const end = length == null ? reader.len : reader.pos + length + const end = length == null ? r.len : r.pos + length - while (reader.pos < end) { - const tag = reader.uint32() + while (r.pos < end) { + const tag = r.uint32() switch (tag >>> 3) { case 1: { - obj.field1 = reader.bool() + obj.field1 = r.bool() break } case 2: { @@ -1218,7 +1218,7 @@ export namespace MessageWithPrimitiveMap { throw new MaxSizeError('Decode error - map field "nestedStrings" had too many elements') } - const entry = MessageWithPrimitiveMap.MessageWithPrimitiveMap$nestedStringsEntry.codec().decode(reader, reader.uint32(), { + const entry = MessageWithPrimitiveMap.MessageWithPrimitiveMap$nestedStringsEntry.codec().decode(r, r.uint32(), { limits: { value: opts.limits?.nestedStrings$value } @@ -1227,19 +1227,19 @@ export namespace MessageWithPrimitiveMap { break } default: { - reader.skipType(tag & 7) + r.skipType(tag & 7) break } } } return obj - }, function * (reader, length, prefix, opts = {}) { + }, function * (r, length, prefix, opts = {}) { const obj = { nestedStrings: 0 } - const end = length == null ? reader.len : reader.pos + length + const end = length == null ? r.len : r.pos + length if (prefix !== '.') { yield { @@ -1249,14 +1249,14 @@ export namespace MessageWithPrimitiveMap { } } - while (reader.pos < end) { - const tag = reader.uint32() + while (r.pos < end) { + const tag = r.uint32() switch (tag >>> 3) { case 1: { yield { field: `${prefix}field1`, - value: reader.bool() + value: r.bool() } break } @@ -1265,7 +1265,7 @@ export namespace MessageWithPrimitiveMap { throw new MaxLengthError('Decode error - map field "nestedStrings" had too many elements') } - yield * MessageWithPrimitiveMap.MessageWithPrimitiveMap$nestedStringsEntry.codec().stream(reader, reader.uint32(), `${prefix}nestedStrings{}.`, { + yield * MessageWithPrimitiveMap.MessageWithPrimitiveMap$nestedStringsEntry.codec().stream(r, r.uint32(), `${prefix}nestedStrings{}.`, { limits: { value: opts.limits?.nestedStrings$value } @@ -1276,7 +1276,7 @@ export namespace MessageWithPrimitiveMap { break } default: { - reader.skipType(tag & 7) + r.skipType(tag & 7) break } } @@ -1367,20 +1367,20 @@ export namespace MessageWithRepeatedEnums { if (opts.lengthDelimited !== false) { w.ldelim() } - }, (reader, length, opts = {}) => { + }, (r, length, opts = {}) => { const obj: any = { field1: false, enums: [] } - const end = length == null ? reader.len : reader.pos + length + const end = length == null ? r.len : r.pos + length - while (reader.pos < end) { - const tag = reader.uint32() + while (r.pos < end) { + const tag = r.uint32() switch (tag >>> 3) { case 1: { - obj.field1 = reader.bool() + obj.field1 = r.bool() break } case 2: { @@ -1388,23 +1388,23 @@ export namespace MessageWithRepeatedEnums { throw new MaxLengthError('Decode error - repeated field "enums" had too many elements') } - obj.enums.push(ENUM.codec().decode(reader)) + obj.enums.push(ENUM.codec().decode(r)) break } default: { - reader.skipType(tag & 7) + r.skipType(tag & 7) break } } } return obj - }, function * (reader, length, prefix, opts = {}) { + }, function * (r, length, prefix, opts = {}) { const obj = { enums: 0 } - const end = length == null ? reader.len : reader.pos + length + const end = length == null ? r.len : r.pos + length if (prefix !== '.') { yield { @@ -1414,14 +1414,14 @@ export namespace MessageWithRepeatedEnums { } } - while (reader.pos < end) { - const tag = reader.uint32() + while (r.pos < end) { + const tag = r.uint32() switch (tag >>> 3) { case 1: { yield { field: `${prefix}field1`, - value: reader.bool() + value: r.bool() } break } @@ -1433,7 +1433,7 @@ export namespace MessageWithRepeatedEnums { yield { field: `${prefix}enums[]`, index: obj.enums, - value: ENUM.codec().decode(reader) + value: ENUM.codec().decode(r) } obj.enums++ @@ -1441,7 +1441,7 @@ export namespace MessageWithRepeatedEnums { break } default: { - reader.skipType(tag & 7) + r.skipType(tag & 7) break } } diff --git a/packages/protons/test/fixtures/test.ts b/packages/protons/test/fixtures/test.ts index 6f9be94..d6de192 100644 --- a/packages/protons/test/fixtures/test.ts +++ b/packages/protons/test/fixtures/test.ts @@ -40,31 +40,31 @@ export namespace SubMessage { if (opts.lengthDelimited !== false) { w.ldelim() } - }, (reader, length, opts = {}) => { + }, (r, length, opts = {}) => { const obj: any = { foo: '' } - const end = length == null ? reader.len : reader.pos + length + const end = length == null ? r.len : r.pos + length - while (reader.pos < end) { - const tag = reader.uint32() + while (r.pos < end) { + const tag = r.uint32() switch (tag >>> 3) { case 1: { - obj.foo = reader.string() + obj.foo = r.string() break } default: { - reader.skipType(tag & 7) + r.skipType(tag & 7) break } } } return obj - }, function * (reader, length, prefix, opts = {}) { - const end = length == null ? reader.len : reader.pos + length + }, function * (r, length, prefix, opts = {}) { + const end = length == null ? r.len : r.pos + length if (prefix !== '.') { yield { @@ -74,19 +74,19 @@ export namespace SubMessage { } } - while (reader.pos < end) { - const tag = reader.uint32() + while (r.pos < end) { + const tag = r.uint32() switch (tag >>> 3) { case 1: { yield { field: `${prefix}foo`, - value: reader.string() + value: r.string() } break } default: { - reader.skipType(tag & 7) + r.skipType(tag & 7) break } } @@ -249,67 +249,67 @@ export namespace AllTheTypes { if (opts.lengthDelimited !== false) { w.ldelim() } - }, (reader, length, opts = {}) => { + }, (r, length, opts = {}) => { const obj: any = { field14: [] } - const end = length == null ? reader.len : reader.pos + length + const end = length == null ? r.len : r.pos + length - while (reader.pos < end) { - const tag = reader.uint32() + while (r.pos < end) { + const tag = r.uint32() switch (tag >>> 3) { case 1: { - obj.field1 = reader.bool() + obj.field1 = r.bool() break } case 2: { - obj.field2 = reader.int32() + obj.field2 = r.int32() break } case 3: { - obj.field3 = reader.int64() + obj.field3 = r.int64() break } case 4: { - obj.field4 = reader.uint32() + obj.field4 = r.uint32() break } case 5: { - obj.field5 = reader.uint64() + obj.field5 = r.uint64() break } case 6: { - obj.field6 = reader.sint32() + obj.field6 = r.sint32() break } case 7: { - obj.field7 = reader.sint64() + obj.field7 = r.sint64() break } case 8: { - obj.field8 = reader.double() + obj.field8 = r.double() break } case 9: { - obj.field9 = reader.float() + obj.field9 = r.float() break } case 10: { - obj.field10 = reader.string() + obj.field10 = r.string() break } case 11: { - obj.field11 = reader.bytes() + obj.field11 = r.bytes() break } case 12: { - obj.field12 = AnEnum.codec().decode(reader) + obj.field12 = AnEnum.codec().decode(r) break } case 13: { - obj.field13 = SubMessage.codec().decode(reader, reader.uint32(), { + obj.field13 = SubMessage.codec().decode(r, r.uint32(), { limits: opts.limits?.field13 }) break @@ -319,39 +319,39 @@ export namespace AllTheTypes { throw new MaxLengthError('Decode error - repeated field "field14" had too many elements') } - obj.field14.push(reader.string()) + obj.field14.push(r.string()) break } case 15: { - obj.field15 = reader.fixed32() + obj.field15 = r.fixed32() break } case 16: { - obj.field16 = reader.fixed64() + obj.field16 = r.fixed64() break } case 17: { - obj.field17 = reader.sfixed32() + obj.field17 = r.sfixed32() break } case 18: { - obj.field18 = reader.sfixed64() + obj.field18 = r.sfixed64() break } default: { - reader.skipType(tag & 7) + r.skipType(tag & 7) break } } } return obj - }, function * (reader, length, prefix, opts = {}) { + }, function * (r, length, prefix, opts = {}) { const obj = { field14: 0 } - const end = length == null ? reader.len : reader.pos + length + const end = length == null ? r.len : r.pos + length if (prefix !== '.') { yield { @@ -361,96 +361,96 @@ export namespace AllTheTypes { } } - while (reader.pos < end) { - const tag = reader.uint32() + while (r.pos < end) { + const tag = r.uint32() switch (tag >>> 3) { case 1: { yield { field: `${prefix}field1`, - value: reader.bool() + value: r.bool() } break } case 2: { yield { field: `${prefix}field2`, - value: reader.int32() + value: r.int32() } break } case 3: { yield { field: `${prefix}field3`, - value: reader.int64() + value: r.int64() } break } case 4: { yield { field: `${prefix}field4`, - value: reader.uint32() + value: r.uint32() } break } case 5: { yield { field: `${prefix}field5`, - value: reader.uint64() + value: r.uint64() } break } case 6: { yield { field: `${prefix}field6`, - value: reader.sint32() + value: r.sint32() } break } case 7: { yield { field: `${prefix}field7`, - value: reader.sint64() + value: r.sint64() } break } case 8: { yield { field: `${prefix}field8`, - value: reader.double() + value: r.double() } break } case 9: { yield { field: `${prefix}field9`, - value: reader.float() + value: r.float() } break } case 10: { yield { field: `${prefix}field10`, - value: reader.string() + value: r.string() } break } case 11: { yield { field: `${prefix}field11`, - value: reader.bytes() + value: r.bytes() } break } case 12: { yield { field: `${prefix}field12`, - value: AnEnum.codec().decode(reader) + value: AnEnum.codec().decode(r) } break } case 13: { - yield * SubMessage.codec().stream(reader, reader.uint32(), `${prefix}field13.`, { + yield * SubMessage.codec().stream(r, r.uint32(), `${prefix}field13.`, { limits: opts.limits?.field13 }) @@ -464,7 +464,7 @@ export namespace AllTheTypes { yield { field: `${prefix}field14[]`, index: obj.field14, - value: reader.string() + value: r.string() } obj.field14++ @@ -474,33 +474,33 @@ export namespace AllTheTypes { case 15: { yield { field: `${prefix}field15`, - value: reader.fixed32() + value: r.fixed32() } break } case 16: { yield { field: `${prefix}field16`, - value: reader.fixed64() + value: r.fixed64() } break } case 17: { yield { field: `${prefix}field17`, - value: reader.sfixed32() + value: r.sfixed32() } break } case 18: { yield { field: `${prefix}field18`, - value: reader.sfixed64() + value: r.sfixed64() } break } default: { - reader.skipType(tag & 7) + r.skipType(tag & 7) break } } diff --git a/packages/protons/test/oneof.spec.ts b/packages/protons/test/oneof.spec.ts index 2700dd0..1788a46 100644 --- a/packages/protons/test/oneof.spec.ts +++ b/packages/protons/test/oneof.spec.ts @@ -1,124 +1,6 @@ import { expect } from 'aegir/chai' -import Long from 'long' -import protobufjs from 'protobufjs' import { EnumType, MessageWithoutOneOfs, OneOfMessage } from './fixtures/oneof.ts' - -function longifyBigInts (obj: any): any { - const output = { - ...obj - } - - for (const key of Object.keys(output)) { - if (typeof output[key] === 'bigint') { - output[key] = Long.fromString(`${output[key].toString()}`) - } - } - - return output -} - -function bigintifyLongs (obj: any): any { - const output = { - ...obj - } - - for (const key of Object.keys(output)) { - if (output[key]?.low != null && output[key]?.high != null) { - output[key] = BigInt(new Long(output[key].low, output[key].high, output[key].unsigned).toString()) - } - } - - return output -} - -function uint8ArrayifyBytes (obj: any): any { - const output = { - ...obj - } - - for (const key of Object.keys(output)) { - if (output[key] instanceof Uint8Array) { - output[key] = Uint8Array.from(output[key]) - } - } - - return output -} - -function objectifyMaps (obj: any): any { - const output = { - ...obj - } - - for (const key of Object.keys(output)) { - if (output[key] instanceof Map) { - const obj: Record = {} - const entries: MapIterator<[any, any]> = output[key].entries() - - for (const [key, value] of entries) { - obj[key] = value - } - - output[key] = obj - } - } - - return output -} - -/** - * Paper over differences between protons and protobuf.js output - */ -function normalizeProtonbufjs (obj: any, target: any): any { - let output = bigintifyLongs(obj) - output = uint8ArrayifyBytes(output) - - for (const key of Object.keys(output)) { - // protobufjs sets unset message fields to `null`, protons does not set the field at all - if (output[key] === null && target[key] == null) { - delete output[key] - } - } - - for (const key of Object.keys(target)) { - // protobufjs uses plain objects instead of maps - if (target[key] instanceof Map) { - output[key] = new Map(Object.entries(output[key] ?? {})) - } - } - - return output -} - -interface TestEncodingOptions { - compareBytes?: boolean - comparePbjs?: boolean -} - -/** - * Ensure: - * - * 1. the generated bytes between protons, pbjs and protobuf.js are the same - * 2. protons and protobuf.js agree on deserialization - */ -function testEncodings (obj: any, protons: any, proto: string, typeName: string, opts: TestEncodingOptions = {}): void { - const protobufJsSchema = protobufjs.loadSync(proto).lookupType(typeName) - const protobufJsBuf = protobufJsSchema.encode(protobufJsSchema.fromObject(objectifyMaps(longifyBigInts(obj)))).finish() - - const encoded = protons.encode(obj) - - if (opts.compareBytes !== false) { - expect(encoded).to.equalBytes(protobufJsBuf) - } - - expect(protons.decode(encoded)).to.deep.equal(obj) - expect(protons.decode(protobufJsBuf)).to.deep.equal(obj) - - expect(normalizeProtonbufjs(protobufJsSchema.toObject(protobufJsSchema.decode(encoded), { - enums: String, - defaults: true - }), obj)).to.deep.equal(obj) -} +import { testEncodings } from './utils/compat.ts' describe('oneof', () => { it('should only encode one field', () => { diff --git a/packages/protons/test/packed.spec.ts b/packages/protons/test/packed.spec.ts new file mode 100644 index 0000000..1f0234c --- /dev/null +++ b/packages/protons/test/packed.spec.ts @@ -0,0 +1,154 @@ +import { expect } from 'aegir/chai' +import all from 'it-all' +import { fromString as uint8ArrayFromString } from 'uint8arrays/from-string' +import { toString as uint8ArrayToString } from 'uint8arrays/to-string' +import { DefaultPackedTypes, ExpandedTypes, NewOptionExpandedTypes, NewOptionPackedTypes, PackedTypes, SpecPacked } from './fixtures/packed.ts' +import { testEncodings } from './utils/compat.ts' + +describe('packed', () => { + it('encodes the spec example', () => { + const obj: SpecPacked = { + str: 'hello', + packed: [1, 2, 3] + } + + const buf = SpecPacked.encode(obj) + + const str = uint8ArrayToString(buf, 'base16') + expect(str).to.equal('220568656c6c6f2a03010203') + }) + + it('decodes the spec example', () => { + const buf = uint8ArrayFromString('220568656c6c6f2a03010203', 'base16') + const obj = SpecPacked.decode(buf) + + expect(obj).to.deep.equal({ + str: 'hello', + packed: [1, 2, 3] + }) + }) + + it('streams the spec example', () => { + const buf = uint8ArrayFromString('220568656c6c6f2a03010203', 'base16') + const events = all(SpecPacked.stream(buf)) + + expect(events).to.deep.equal([{ + field: '.str', + value: 'hello' + }, { + field: '.packed[]', + index: 0, + value: 1 + }, { + field: '.packed[]', + index: 1, + value: 2 + }, { + field: '.packed[]', + index: 2, + value: 3 + }]) + }) + + // protobufjs doesn't pack by default for proto3 and later but it should? + it('should encode default packed types to same bytes as other implementations', () => { + const obj: DefaultPackedTypes = { + doubles: [1.0, 2.0, 3.0], + floats: [1.0, 2.0, 3.0], + int32s: [1, 2, 3], + int64s: [1n, 2n, 3n], + uint32s: [1, 2, 3], + uint64s: [1n, 2n, 3n], + sint32s: [1, 2, 3], + sint64s: [1n, 2n, 3n], + fixed32s: [1, 2, 3], + fixed64s: [1n, 2n, 3n], + sfixed32s: [1, 2, 3], + sfixed64s: [1n, 2n, 3n], + bools: [true, true, false] + } + + testEncodings(obj, DefaultPackedTypes, './test/fixtures/packed.proto', 'DefaultPackedTypes') + }) + + // protobufjs doesn't understand [packed=true|false] + it('should encode packed types to same bytes as other implementations', () => { + const obj: PackedTypes = { + doubles: [1.0, 2.0, 3.0], + floats: [1.0, 2.0, 3.0], + int32s: [1, 2, 3], + int64s: [1n, 2n, 3n], + uint32s: [1, 2, 3], + uint64s: [1n, 2n, 3n], + sint32s: [1, 2, 3], + sint64s: [1n, 2n, 3n], + fixed32s: [1, 2, 3], + fixed64s: [1n, 2n, 3n], + sfixed32s: [1, 2, 3], + sfixed64s: [1n, 2n, 3n], + bools: [true, true, false] + } + + testEncodings(obj, PackedTypes, './test/fixtures/packed.proto', 'PackedTypes') + }) + + it('should encode expanded types to same bytes as other implementations', () => { + const obj: ExpandedTypes = { + doubles: [1.0, 2.0, 3.0], + floats: [1.0, 2.0, 3.0], + int32s: [1, 2, 3], + int64s: [1n, 2n, 3n], + uint32s: [1, 2, 3], + uint64s: [1n, 2n, 3n], + sint32s: [1, 2, 3], + sint64s: [1n, 2n, 3n], + fixed32s: [1, 2, 3], + fixed64s: [1n, 2n, 3n], + sfixed32s: [1, 2, 3], + sfixed64s: [1n, 2n, 3n], + bools: [true, true, false] + } + + testEncodings(obj, ExpandedTypes, './test/fixtures/packed.proto', 'ExpandedTypes') + }) + + it('should encode new option packed types to same bytes as other implementations', () => { + const obj: NewOptionPackedTypes = { + doubles: [1.0, 2.0, 3.0], + floats: [1.0, 2.0, 3.0], + int32s: [1, 2, 3], + int64s: [1n, 2n, 3n], + uint32s: [1, 2, 3], + uint64s: [1n, 2n, 3n], + sint32s: [1, 2, 3], + sint64s: [1n, 2n, 3n], + fixed32s: [1, 2, 3], + fixed64s: [1n, 2n, 3n], + sfixed32s: [1, 2, 3], + sfixed64s: [1n, 2n, 3n], + bools: [true, true, false] + } + + testEncodings(obj, NewOptionPackedTypes, './test/fixtures/packed.proto', 'NewOptionPackedTypes') + }) + + it('should encode new option expanded types to same bytes as other implementations', () => { + const obj: NewOptionExpandedTypes = { + doubles: [1.0, 2.0, 3.0], + floats: [1.0, 2.0, 3.0], + int32s: [1, 2, 3], + int64s: [1n, 2n, 3n], + uint32s: [1, 2, 3], + uint64s: [1n, 2n, 3n], + sint32s: [1, 2, 3], + sint64s: [1n, 2n, 3n], + fixed32s: [1, 2, 3], + fixed64s: [1n, 2n, 3n], + sfixed32s: [1, 2, 3], + sfixed64s: [1n, 2n, 3n], + bools: [true, true, false] + } + + testEncodings(obj, NewOptionExpandedTypes, './test/fixtures/packed.proto', 'NewOptionExpandedTypes') + }) +}) diff --git a/packages/protons/test/utils/compat.ts b/packages/protons/test/utils/compat.ts new file mode 100644 index 0000000..6015e10 --- /dev/null +++ b/packages/protons/test/utils/compat.ts @@ -0,0 +1,152 @@ +import { expect } from 'aegir/chai' +import Long from 'long' +import protobufjs from 'protobufjs' + +function longifyBigInts (obj: any): any { + const output = { + ...obj + } + + for (const key of Object.keys(output)) { + const value = output[key] + + if (typeof value === 'bigint') { + output[key] = Long.fromString(`${value.toString()}`) + } + + if (Array.isArray(value)) { + const v = [] + + for (const val of value) { + if (typeof val === 'bigint') { + v.push(Long.fromString(`${val.toString()}`)) + } else { + v.push(val) + } + } + + output[key] = v + } + } + + return output +} + +function bigintifyLongs (obj: any): any { + const output = { + ...obj + } + + for (const key of Object.keys(output)) { + const value = output[key] + + if (Array.isArray(value)) { + const v = [] + + for (let i = 0; i < value.length; i++) { + const val = value[i] + + if (val?.low != null && val?.high != null) { + v.push(BigInt(new Long(val.low, val.high, val.unsigned).toString())) + } else { + v.push(val) + } + } + + output[key] = v + } else if (value?.low != null && value?.high != null) { + output[key] = BigInt(new Long(value.low, value.high, value.unsigned).toString()) + } + } + + return output +} + +function uint8ArrayifyBytes (obj: any): any { + const output = { + ...obj + } + + for (const key of Object.keys(output)) { + if (output[key] instanceof Uint8Array) { + output[key] = Uint8Array.from(output[key]) + } + } + + return output +} + +function objectifyMaps (obj: any): any { + const output = { + ...obj + } + + for (const key of Object.keys(output)) { + if (output[key] instanceof Map) { + const obj: Record = {} + const entries: MapIterator<[any, any]> = output[key].entries() + + for (const [key, value] of entries) { + obj[key] = value + } + + output[key] = obj + } + } + + return output +} + +/** + * Paper over differences between protons and protobuf.js output + */ +function normalizeProtonbufjs (obj: any, target: any): any { + let output = bigintifyLongs(obj) + output = uint8ArrayifyBytes(output) + + for (const key of Object.keys(output)) { + // protobufjs sets unset message fields to `null`, protons does not set the field at all + if (output[key] === null && target[key] == null) { + delete output[key] + } + } + + for (const key of Object.keys(target)) { + // protobufjs uses plain objects instead of maps + if (target[key] instanceof Map) { + output[key] = new Map(Object.entries(output[key] ?? {})) + } + } + + return output +} + +export interface TestEncodingOptions { + compareBytes?: boolean + comparePbjs?: boolean +} + +/** + * Ensure: + * + * 1. the generated bytes between protons, pbjs and protobuf.js are the same + * 2. protons and protobuf.js agree on deserialization + */ +export function testEncodings (obj: any, protons: any, proto: string, typeName: string, opts: TestEncodingOptions = {}): void { + const protobufJsSchema = protobufjs.loadSync(proto).lookupType(typeName) + const protobufJsBuf = protobufJsSchema.encode(protobufJsSchema.fromObject(objectifyMaps(longifyBigInts(obj)))).finish() + + const encoded = protons.encode(obj) + + if (opts.compareBytes !== false) { + expect(encoded).to.equalBytes(Uint8Array.from(protobufJsBuf)) + } + + expect(protons.decode(encoded)).to.deep.equal(obj) + expect(protons.decode(protobufJsBuf)).to.deep.equal(obj) + + expect(normalizeProtonbufjs(protobufJsSchema.toObject(protobufJsSchema.decode(encoded), { + enums: String, + defaults: true + }), obj)).to.deep.equal(obj) +} From 9e4639c0e958df3bbe5aa802261d454448f31388 Mon Sep 17 00:00:00 2001 From: achingbrain Date: Thu, 17 Sep 2026 16:41:06 +0300 Subject: [PATCH 2/6] chore: add tests for field-level options --- packages/protons/src/fields/array-field.ts | 28 +- packages/protons/src/fields/enum-field.ts | 3 +- packages/protons/src/fields/field.ts | 4 +- packages/protons/src/fields/map-field.ts | 3 +- packages/protons/src/types/index.ts | 5 + packages/protons/src/types/message.ts | 3 +- .../protons/test/fixtures/packed-global.proto | 11 + .../protons/test/fixtures/packed-global.ts | 298 ++++++++++++++++++ packages/protons/test/packed.spec.ts | 52 +++ 9 files changed, 397 insertions(+), 10 deletions(-) create mode 100644 packages/protons/test/fixtures/packed-global.proto create mode 100644 packages/protons/test/fixtures/packed-global.ts diff --git a/packages/protons/src/fields/array-field.ts b/packages/protons/src/fields/array-field.ts index e07a26d..a2604ba 100644 --- a/packages/protons/src/fields/array-field.ts +++ b/packages/protons/src/fields/array-field.ts @@ -28,25 +28,43 @@ const PACKABLE_TYPES = [ 'bool' ] +function useExpandedEncoding (fieldOptions?: Record, globalOptions?: Record): boolean { + if (fieldOptions?.features?.repeated_field_encoding === 'EXPANDED') { + return true + } + + if (fieldOptions?.features?.repeated_field_encoding === 'PACKED') { + return false + } + + if (globalOptions?.features?.repeated_field_encoding === 'EXPANDED') { + return true + } + + if (globalOptions?.features?.repeated_field_encoding === 'PACKED') { + return false + } + + return false +} + export class ArrayField extends Field { private lengthLimit?: number private packed: boolean - constructor (name: string, def: ArrayFieldDef, parent: Parent) { + constructor (name: string, def: ArrayFieldDef, parent: Message) { super(name, def, parent) this.lengthLimit = def.options?.['(protons.options).limit'] - // console.info(parent) - const type = parent.findType(this.type).pbType const supportsPacked = PACKABLE_TYPES.indexOf(type) !== -1 // the default from protobuf3 onwards this.packed = supportsPacked - // check user override - if (def.options?.packed === false || def.options?.features?.repeated_field_encoding === 'EXPANDED') { + // check user overrides for field encoding + if (useExpandedEncoding(def.options, parent.def.options)) { this.packed = false } diff --git a/packages/protons/src/fields/enum-field.ts b/packages/protons/src/fields/enum-field.ts index 21160ce..8c1deef 100644 --- a/packages/protons/src/fields/enum-field.ts +++ b/packages/protons/src/fields/enum-field.ts @@ -2,11 +2,12 @@ import { Enum } from '../types/enum.ts' import { Field } from './field.ts' import type { FieldDef } from './field.ts' import type { Parent } from '../types/index.ts' +import type { Message } from '../types/message.ts' export class EnumField extends Field { private enum: Enum - constructor (name: string, def: FieldDef, parent: Parent) { + constructor (name: string, def: FieldDef, parent: Message) { super(name, def, parent) const type = parent.findType(def.type) diff --git a/packages/protons/src/fields/field.ts b/packages/protons/src/fields/field.ts index 1f44609..f9d90a8 100644 --- a/packages/protons/src/fields/field.ts +++ b/packages/protons/src/fields/field.ts @@ -94,9 +94,9 @@ export class Field implements MessageField { public proto2Required: boolean public jsTypeOverride?: 'string' | 'number' public oneof?: string[] - protected parent: Parent + protected parent: Message - constructor (name: string, def: FieldDef, parent: Parent) { + constructor (name: string, def: FieldDef, parent: Message) { this.id = def.id this.name = name this.parent = parent diff --git a/packages/protons/src/fields/map-field.ts b/packages/protons/src/fields/map-field.ts index 5b37827..0939427 100644 --- a/packages/protons/src/fields/map-field.ts +++ b/packages/protons/src/fields/map-field.ts @@ -1,6 +1,7 @@ import { codecTypes, Field, jsTypeOverrides } from './field.ts' import type { FieldDef } from './field.ts' import type { Parent } from '../types/index.ts' +import type { Message } from '../types/message.ts' export interface MapFieldDef extends FieldDef { keyType?: string @@ -19,7 +20,7 @@ export class MapField extends Field { public jsValueTypeOverride?: 'string' | 'number' private lengthLimit?: number - constructor (name: string, def: MapFieldDef, parent: Parent) { + constructor (name: string, def: MapFieldDef, parent: Message) { super(name, def, parent) this.type = 'message' diff --git a/packages/protons/src/types/index.ts b/packages/protons/src/types/index.ts index 63834b0..0fb6cc4 100644 --- a/packages/protons/src/types/index.ts +++ b/packages/protons/src/types/index.ts @@ -1,5 +1,6 @@ import type { Field } from '../fields/field.ts' import type { Flags } from '../index.ts' +import type { MessageDef } from './message.ts' import type { Module } from './module.ts' export interface Type { @@ -19,3 +20,7 @@ export interface Parent { addTypeImport (module: string, symbol: string, alias?: string): void addEslintIgnore (rule: string): void } + +export interface Message extends Parent { + def: MessageDef +} diff --git a/packages/protons/src/types/message.ts b/packages/protons/src/types/message.ts index 145e4f0..68e32e1 100644 --- a/packages/protons/src/types/message.ts +++ b/packages/protons/src/types/message.ts @@ -27,6 +27,7 @@ function camelize (input: string): string { } export interface MessageDef { + options?: Record fields?: Record oneofs?: Record nested?: Record @@ -42,7 +43,7 @@ export class Message implements Type { public fields: Field[] public oneOfs: string[][] public nested: Record - private def: MessageDef + public def: MessageDef private parent: Parent constructor (pbType: string, jsType: string, def: MessageDef, parent: Parent) { diff --git a/packages/protons/test/fixtures/packed-global.proto b/packages/protons/test/fixtures/packed-global.proto new file mode 100644 index 0000000..bb6c861 --- /dev/null +++ b/packages/protons/test/fixtures/packed-global.proto @@ -0,0 +1,11 @@ +syntax = "proto3"; + +option features.repeated_field_encoding = EXPANDED; + +message GlobalPacked { + repeated int32 expanded = 1; + repeated int32 packed_old_option = 2 [packed=true]; + repeated int32 expanded_old_option = 3 [packed=false]; + repeated int32 packed_new_option = 4 [features.repeated_field_encoding=PACKED]; + repeated int32 expanded_new_option = 5 [features.repeated_field_encoding=EXPANDED]; +} diff --git a/packages/protons/test/fixtures/packed-global.ts b/packages/protons/test/fixtures/packed-global.ts new file mode 100644 index 0000000..aa82860 --- /dev/null +++ b/packages/protons/test/fixtures/packed-global.ts @@ -0,0 +1,298 @@ +import { decodeMessage, encodeMessage, MaxLengthError, message, reader, streamMessage } from 'protons-runtime' +import type { Codec, DecodeOptions } from 'protons-runtime' +import type { Uint8ArrayList } from 'uint8arraylist' + +export interface GlobalPacked { + expanded: number[] + packedOldOption: number[] + expandedOldOption: number[] + packedNewOption: number[] + expandedNewOption: number[] +} + +export namespace GlobalPacked { + let _codec: Codec + + export const codec = (): Codec => { + if (_codec == null) { + _codec = message((obj, w, opts = {}) => { + if (opts.lengthDelimited !== false) { + w.fork() + } + + if (obj.expanded != null && obj.expanded.length > 0) { + for (const value of obj.expanded) { + w.uint32(8) + w.int32(value) + } + } + + if (obj.packedOldOption != null && obj.packedOldOption.length > 0) { + for (const value of obj.packedOldOption) { + w.uint32(16) + w.int32(value) + } + } + + if (obj.expandedOldOption != null && obj.expandedOldOption.length > 0) { + for (const value of obj.expandedOldOption) { + w.uint32(24) + w.int32(value) + } + } + + if (obj.packedNewOption != null && obj.packedNewOption.length > 0) { + w.uint32(34) + w.fork() + + for (const value of obj.packedNewOption) { + w.int32(value) + } + + w.ldelim() + } + + if (obj.expandedNewOption != null && obj.expandedNewOption.length > 0) { + for (const value of obj.expandedNewOption) { + w.uint32(40) + w.int32(value) + } + } + + if (opts.lengthDelimited !== false) { + w.ldelim() + } + }, (r, length, opts = {}) => { + const obj: any = { + expanded: [], + packedOldOption: [], + expandedOldOption: [], + packedNewOption: [], + expandedNewOption: [] + } + + const end = length == null ? r.len : r.pos + length + + while (r.pos < end) { + const tag = r.uint32() + + switch (tag >>> 3) { + case 1: { + if (opts.limits?.expanded != null && obj.expanded.length === opts.limits.expanded) { + throw new MaxLengthError('Decode error - repeated field "expanded" had too many elements') + } + + obj.expanded.push(r.int32()) + break + } + case 2: { + if (opts.limits?.packedOldOption != null && obj.packedOldOption.length === opts.limits.packedOldOption) { + throw new MaxLengthError('Decode error - repeated field "packedOldOption" had too many elements') + } + + obj.packedOldOption.push(r.int32()) + break + } + case 3: { + if (opts.limits?.expandedOldOption != null && obj.expandedOldOption.length === opts.limits.expandedOldOption) { + throw new MaxLengthError('Decode error - repeated field "expandedOldOption" had too many elements') + } + + obj.expandedOldOption.push(r.int32()) + break + } + case 4: { + const b = r.bytes() + const r2 = reader(b) + + while (r2.pos < r2.len) { + if (opts.limits?.packedNewOption != null && obj.packedNewOption.length === opts.limits.packedNewOption) { + throw new MaxLengthError('Decode error - repeated field "packedNewOption" had too many elements') + } + + obj.packedNewOption.push(r2.int32()) + } + + break + } + case 5: { + if (opts.limits?.expandedNewOption != null && obj.expandedNewOption.length === opts.limits.expandedNewOption) { + throw new MaxLengthError('Decode error - repeated field "expandedNewOption" had too many elements') + } + + obj.expandedNewOption.push(r.int32()) + break + } + default: { + r.skipType(tag & 7) + break + } + } + } + + return obj + }, function * (r, length, prefix, opts = {}) { + const obj = { + expanded: 0, + packedOldOption: 0, + expandedOldOption: 0, + packedNewOption: 0, + expandedNewOption: 0 + } + + const end = length == null ? r.len : r.pos + length + + if (prefix !== '.') { + yield { + field: prefix.endsWith('.') ? prefix.substring(0, prefix.length - 1) : prefix, + type: 'start', + message: 'GlobalPacked' + } + } + + while (r.pos < end) { + const tag = r.uint32() + + switch (tag >>> 3) { + case 1: { + if (opts.limits?.expanded != null && obj.expanded === opts.limits.expanded) { + throw new MaxLengthError('Streaming decode error - repeated field "expanded" had too many elements') + } + + yield { + field: `${prefix}expanded[]`, + index: obj.expanded, + value: r.int32() + } + + obj.expanded++ + + break + } + case 2: { + if (opts.limits?.packedOldOption != null && obj.packedOldOption === opts.limits.packedOldOption) { + throw new MaxLengthError('Streaming decode error - repeated field "packedOldOption" had too many elements') + } + + yield { + field: `${prefix}packedOldOption[]`, + index: obj.packedOldOption, + value: r.int32() + } + + obj.packedOldOption++ + + break + } + case 3: { + if (opts.limits?.expandedOldOption != null && obj.expandedOldOption === opts.limits.expandedOldOption) { + throw new MaxLengthError('Streaming decode error - repeated field "expandedOldOption" had too many elements') + } + + yield { + field: `${prefix}expandedOldOption[]`, + index: obj.expandedOldOption, + value: r.int32() + } + + obj.expandedOldOption++ + + break + } + case 4: { + const b = r.bytes() + const r2 = reader(b) + + while (r2.pos < r2.len) { + if (opts.limits?.packedNewOption != null && obj.packedNewOption === opts.limits.packedNewOption) { + throw new MaxLengthError('Streaming decode error - repeated field "packedNewOption" had too many elements') + } + + yield { + field: `${prefix}packedNewOption[]`, + index: obj.packedNewOption, + value: r2.int32() + } + + obj.packedNewOption++ + } + + break + } + case 5: { + if (opts.limits?.expandedNewOption != null && obj.expandedNewOption === opts.limits.expandedNewOption) { + throw new MaxLengthError('Streaming decode error - repeated field "expandedNewOption" had too many elements') + } + + yield { + field: `${prefix}expandedNewOption[]`, + index: obj.expandedNewOption, + value: r.int32() + } + + obj.expandedNewOption++ + + break + } + default: { + r.skipType(tag & 7) + break + } + } + } + + if (prefix !== '.') { + yield { + field: prefix.endsWith('.') ? prefix.substring(0, prefix.length - 1) : prefix, + type: 'end', + message: 'GlobalPacked' + } + } + }) + } + + return _codec + } + + export interface GlobalPackedExpandedFieldEvent { + field: '.expanded[]' + index: number + value: number + } + + export interface GlobalPackedPackedOldOptionFieldEvent { + field: '.packedOldOption[]' + index: number + value: number + } + + export interface GlobalPackedExpandedOldOptionFieldEvent { + field: '.expandedOldOption[]' + index: number + value: number + } + + export interface GlobalPackedPackedNewOptionFieldEvent { + field: '.packedNewOption[]' + index: number + value: number + } + + export interface GlobalPackedExpandedNewOptionFieldEvent { + field: '.expandedNewOption[]' + index: number + value: number + } + + export function encode (obj: Partial): Uint8Array { + return encodeMessage(obj, GlobalPacked.codec()) + } + + export function decode (buf: Uint8Array | Uint8ArrayList, opts?: DecodeOptions): GlobalPacked { + return decodeMessage(buf, GlobalPacked.codec(), opts) + } + + export function stream (buf: Uint8Array | Uint8ArrayList, opts?: DecodeOptions): Generator { + return streamMessage(buf, GlobalPacked.codec(), opts) + } +} diff --git a/packages/protons/test/packed.spec.ts b/packages/protons/test/packed.spec.ts index 1f0234c..aef6427 100644 --- a/packages/protons/test/packed.spec.ts +++ b/packages/protons/test/packed.spec.ts @@ -2,6 +2,7 @@ import { expect } from 'aegir/chai' import all from 'it-all' import { fromString as uint8ArrayFromString } from 'uint8arrays/from-string' import { toString as uint8ArrayToString } from 'uint8arrays/to-string' +import { GlobalPacked } from './fixtures/packed-global.ts' import { DefaultPackedTypes, ExpandedTypes, NewOptionExpandedTypes, NewOptionPackedTypes, PackedTypes, SpecPacked } from './fixtures/packed.ts' import { testEncodings } from './utils/compat.ts' @@ -151,4 +152,55 @@ describe('packed', () => { testEncodings(obj, NewOptionExpandedTypes, './test/fixtures/packed.proto', 'NewOptionExpandedTypes') }) + + it('should respect global options', () => { + expect(uint8ArrayToString(GlobalPacked.encode({ + expanded: [1, 1], + packedOldOption: [], + expandedOldOption: [], + packedNewOption: [], + expandedNewOption: [] + }), 'base16')).to.equal('08010801', 'file-level repeated-field-encoding set to expanded ignored') + + expect(uint8ArrayToString(GlobalPacked.encode({ + expanded: [], + packedOldOption: [1, 1], + expandedOldOption: [], + packedNewOption: [], + expandedNewOption: [] + }), 'base16')).to.equal('10011001', 'old field-level repeated-field-encoding set to packed ignored') + + expect(uint8ArrayToString(GlobalPacked.encode({ + expanded: [], + packedOldOption: [], + expandedOldOption: [1, 1], + packedNewOption: [], + expandedNewOption: [] + }), 'base16')).to.equal('18011801', 'old field-level repeated-field-encoding set to expanded ignored') + + expect(uint8ArrayToString(GlobalPacked.encode({ + expanded: [], + packedOldOption: [], + expandedOldOption: [], + packedNewOption: [1, 1], + expandedNewOption: [] + }), 'base16')).to.equal('22020101', 'new field-level repeated-field-encoding set to packed ignored') + + expect(uint8ArrayToString(GlobalPacked.encode({ + expanded: [], + packedOldOption: [], + expandedOldOption: [], + packedNewOption: [], + expandedNewOption: [1, 1] + }), 'base16')).to.equal('28012801', 'new field-level repeated-field-encoding set to expanded ignored') + + testEncodings({ + expanded: [1, 1], + // protobufjs ignores proto2-style [packed=false] field override + packedOldOption: [], + expandedOldOption: [1, 1], + packedNewOption: [1, 1], + expandedNewOption: [1, 1] + }, GlobalPacked, './test/fixtures/packed-global.proto', 'GlobalPacked') + }) }) From f8477ae4fe6504cfd7ec2d676fb8e4a5f2b8b3aa Mon Sep 17 00:00:00 2001 From: achingbrain Date: Fri, 18 Sep 2026 09:46:57 +0300 Subject: [PATCH 3/6] chore: update build --- .../src/implementations/protons/bench.ts | 136 ++-- .../protons/test/fixtures/packed-global.ts | 16 +- packages/protons/test/fixtures/packed.ts | 666 +++++++++++++----- packages/protons/test/packed.spec.ts | 28 +- 4 files changed, 557 insertions(+), 289 deletions(-) diff --git a/packages/protons-benchmark/src/implementations/protons/bench.ts b/packages/protons-benchmark/src/implementations/protons/bench.ts index 5fe5130..fa65f55 100644 --- a/packages/protons-benchmark/src/implementations/protons/bench.ts +++ b/packages/protons-benchmark/src/implementations/protons/bench.ts @@ -28,29 +28,29 @@ export namespace Foo { if (opts.lengthDelimited !== false) { w.ldelim() } - }, (reader, length, opts = {}) => { + }, (r, length, opts = {}) => { const obj: any = {} - const end = length == null ? reader.len : reader.pos + length + const end = length == null ? r.len : r.pos + length - while (reader.pos < end) { - const tag = reader.uint32() + while (r.pos < end) { + const tag = r.uint32() switch (tag >>> 3) { case 1: { - obj.baz = reader.uint32() + obj.baz = r.uint32() break } default: { - reader.skipType(tag & 7) + r.skipType(tag & 7) break } } } return obj - }, function * (reader, length, prefix, opts = {}) { - const end = length == null ? reader.len : reader.pos + length + }, function * (r, length, prefix, opts = {}) { + const end = length == null ? r.len : r.pos + length if (prefix !== '.') { yield { @@ -60,19 +60,19 @@ export namespace Foo { } } - while (reader.pos < end) { - const tag = reader.uint32() + while (r.pos < end) { + const tag = r.uint32() switch (tag >>> 3) { case 1: { yield { field: `${prefix}baz`, - value: reader.uint32() + value: r.uint32() } break } default: { - reader.skipType(tag & 7) + r.skipType(tag & 7) break } } @@ -135,31 +135,31 @@ export namespace Bar { if (opts.lengthDelimited !== false) { w.ldelim() } - }, (reader, length, opts = {}) => { + }, (r, length, opts = {}) => { const obj: any = {} - const end = length == null ? reader.len : reader.pos + length + const end = length == null ? r.len : r.pos + length - while (reader.pos < end) { - const tag = reader.uint32() + while (r.pos < end) { + const tag = r.uint32() switch (tag >>> 3) { case 1: { - obj.tmp = Foo.codec().decode(reader, reader.uint32(), { + obj.tmp = Foo.codec().decode(r, r.uint32(), { limits: opts.limits?.tmp }) break } default: { - reader.skipType(tag & 7) + r.skipType(tag & 7) break } } } return obj - }, function * (reader, length, prefix, opts = {}) { - const end = length == null ? reader.len : reader.pos + length + }, function * (r, length, prefix, opts = {}) { + const end = length == null ? r.len : r.pos + length if (prefix !== '.') { yield { @@ -169,19 +169,19 @@ export namespace Bar { } } - while (reader.pos < end) { - const tag = reader.uint32() + while (r.pos < end) { + const tag = r.uint32() switch (tag >>> 3) { case 1: { - yield * Foo.codec().stream(reader, reader.uint32(), `${prefix}tmp.`, { + yield * Foo.codec().stream(r, r.uint32(), `${prefix}tmp.`, { limits: opts.limits?.tmp }) break } default: { - reader.skipType(tag & 7) + r.skipType(tag & 7) break } } @@ -274,15 +274,15 @@ export namespace Yo { if (opts.lengthDelimited !== false) { w.ldelim() } - }, (reader, length, opts = {}) => { + }, (r, length, opts = {}) => { const obj: any = { lol: [] } - const end = length == null ? reader.len : reader.pos + length + const end = length == null ? r.len : r.pos + length - while (reader.pos < end) { - const tag = reader.uint32() + while (r.pos < end) { + const tag = r.uint32() switch (tag >>> 3) { case 1: { @@ -290,23 +290,23 @@ export namespace Yo { throw new MaxLengthError('Decode error - repeated field "lol" had too many elements') } - obj.lol.push(FOO.codec().decode(reader)) + obj.lol.push(FOO.codec().decode(r)) break } default: { - reader.skipType(tag & 7) + r.skipType(tag & 7) break } } } return obj - }, function * (reader, length, prefix, opts = {}) { + }, function * (r, length, prefix, opts = {}) { const obj = { lol: 0 } - const end = length == null ? reader.len : reader.pos + length + const end = length == null ? r.len : r.pos + length if (prefix !== '.') { yield { @@ -316,8 +316,8 @@ export namespace Yo { } } - while (reader.pos < end) { - const tag = reader.uint32() + while (r.pos < end) { + const tag = r.uint32() switch (tag >>> 3) { case 1: { @@ -328,7 +328,7 @@ export namespace Yo { yield { field: `${prefix}lol[]`, index: obj.lol, - value: FOO.codec().decode(reader) + value: FOO.codec().decode(r) } obj.lol++ @@ -336,7 +336,7 @@ export namespace Yo { break } default: { - reader.skipType(tag & 7) + r.skipType(tag & 7) break } } @@ -407,35 +407,35 @@ export namespace Lol { if (opts.lengthDelimited !== false) { w.ldelim() } - }, (reader, length, opts = {}) => { + }, (r, length, opts = {}) => { const obj: any = {} - const end = length == null ? reader.len : reader.pos + length + const end = length == null ? r.len : r.pos + length - while (reader.pos < end) { - const tag = reader.uint32() + while (r.pos < end) { + const tag = r.uint32() switch (tag >>> 3) { case 1: { - obj.lol = reader.string() + obj.lol = r.string() break } case 2: { - obj.b = Bar.codec().decode(reader, reader.uint32(), { + obj.b = Bar.codec().decode(r, r.uint32(), { limits: opts.limits?.b }) break } default: { - reader.skipType(tag & 7) + r.skipType(tag & 7) break } } } return obj - }, function * (reader, length, prefix, opts = {}) { - const end = length == null ? reader.len : reader.pos + length + }, function * (r, length, prefix, opts = {}) { + const end = length == null ? r.len : r.pos + length if (prefix !== '.') { yield { @@ -445,26 +445,26 @@ export namespace Lol { } } - while (reader.pos < end) { - const tag = reader.uint32() + while (r.pos < end) { + const tag = r.uint32() switch (tag >>> 3) { case 1: { yield { field: `${prefix}lol`, - value: reader.string() + value: r.string() } break } case 2: { - yield * Bar.codec().stream(reader, reader.uint32(), `${prefix}b.`, { + yield * Bar.codec().stream(r, r.uint32(), `${prefix}b.`, { limits: opts.limits?.b }) break } default: { - reader.skipType(tag & 7) + r.skipType(tag & 7) break } } @@ -573,43 +573,43 @@ export namespace Test { if (opts.lengthDelimited !== false) { w.ldelim() } - }, (reader, length, opts = {}) => { + }, (r, length, opts = {}) => { const obj: any = {} - const end = length == null ? reader.len : reader.pos + length + const end = length == null ? r.len : r.pos + length - while (reader.pos < end) { - const tag = reader.uint32() + while (r.pos < end) { + const tag = r.uint32() switch (tag >>> 3) { case 6: { - obj.meh = Lol.codec().decode(reader, reader.uint32(), { + obj.meh = Lol.codec().decode(r, r.uint32(), { limits: opts.limits?.meh }) break } case 3: { - obj.hello = reader.uint32() + obj.hello = r.uint32() break } case 1: { - obj.foo = reader.string() + obj.foo = r.string() break } case 7: { - obj.payload = reader.bytes() + obj.payload = r.bytes() break } default: { - reader.skipType(tag & 7) + r.skipType(tag & 7) break } } } return obj - }, function * (reader, length, prefix, opts = {}) { - const end = length == null ? reader.len : reader.pos + length + }, function * (r, length, prefix, opts = {}) { + const end = length == null ? r.len : r.pos + length if (prefix !== '.') { yield { @@ -619,12 +619,12 @@ export namespace Test { } } - while (reader.pos < end) { - const tag = reader.uint32() + while (r.pos < end) { + const tag = r.uint32() switch (tag >>> 3) { case 6: { - yield * Lol.codec().stream(reader, reader.uint32(), `${prefix}meh.`, { + yield * Lol.codec().stream(r, r.uint32(), `${prefix}meh.`, { limits: opts.limits?.meh }) @@ -633,26 +633,26 @@ export namespace Test { case 3: { yield { field: `${prefix}hello`, - value: reader.uint32() + value: r.uint32() } break } case 1: { yield { field: `${prefix}foo`, - value: reader.string() + value: r.string() } break } case 7: { yield { field: `${prefix}payload`, - value: reader.bytes() + value: r.bytes() } break } default: { - reader.skipType(tag & 7) + r.skipType(tag & 7) break } } diff --git a/packages/protons/test/fixtures/packed-global.ts b/packages/protons/test/fixtures/packed-global.ts index aa82860..8b78a2c 100644 --- a/packages/protons/test/fixtures/packed-global.ts +++ b/packages/protons/test/fixtures/packed-global.ts @@ -10,12 +10,20 @@ export interface GlobalPacked { expandedNewOption: number[] } +export interface GlobalPackedInput { + expanded?: number[] + packedOldOption?: number[] + expandedOldOption?: number[] + packedNewOption?: number[] + expandedNewOption?: number[] +} + export namespace GlobalPacked { - let _codec: Codec + let _codec: Codec - export const codec = (): Codec => { + export const codec = (): Codec => { if (_codec == null) { - _codec = message((obj, w, opts = {}) => { + _codec = message((obj, w, opts = {}) => { if (opts.lengthDelimited !== false) { w.fork() } @@ -284,7 +292,7 @@ export namespace GlobalPacked { value: number } - export function encode (obj: Partial): Uint8Array { + export function encode (obj: GlobalPackedInput): Uint8Array { return encodeMessage(obj, GlobalPacked.codec()) } diff --git a/packages/protons/test/fixtures/packed.ts b/packages/protons/test/fixtures/packed.ts index 2c66df8..584cf60 100644 --- a/packages/protons/test/fixtures/packed.ts +++ b/packages/protons/test/fixtures/packed.ts @@ -7,12 +7,17 @@ export interface SpecPacked { packed: number[] } +export interface SpecPackedInput { + str?: string + packed?: number[] +} + export namespace SpecPacked { - let _codec: Codec + let _codec: Codec - export const codec = (): Codec => { + export const codec = (): Codec => { if (_codec == null) { - _codec = message((obj, w, opts = {}) => { + _codec = message((obj, w, opts = {}) => { if (opts.lengthDelimited !== false) { w.fork() } @@ -151,7 +156,7 @@ export namespace SpecPacked { value: number } - export function encode (obj: Partial): Uint8Array { + export function encode (obj: SpecPackedInput): Uint8Array { return encodeMessage(obj, SpecPacked.codec()) } @@ -180,12 +185,28 @@ export interface DefaultPackedTypes { bools: boolean[] } +export interface DefaultPackedTypesInput { + doubles?: number[] + floats?: number[] + int32s?: number[] + int64s?: bigint[] + uint32s?: number[] + uint64s?: bigint[] + sint32s?: number[] + sint64s?: bigint[] + fixed32s?: number[] + fixed64s?: bigint[] + sfixed32s?: number[] + sfixed64s?: bigint[] + bools?: boolean[] +} + export namespace DefaultPackedTypes { - let _codec: Codec + let _codec: Codec - export const codec = (): Codec => { + export const codec = (): Codec => { if (_codec == null) { - _codec = message((obj, w, opts = {}) => { + _codec = message((obj, w, opts = {}) => { if (opts.lengthDelimited !== false) { w.fork() } @@ -938,7 +959,7 @@ export namespace DefaultPackedTypes { value: boolean } - export function encode (obj: Partial): Uint8Array { + export function encode (obj: DefaultPackedTypesInput): Uint8Array { return encodeMessage(obj, DefaultPackedTypes.codec()) } @@ -967,12 +988,28 @@ export interface PackedTypes { bools: boolean[] } +export interface PackedTypesInput { + doubles?: number[] + floats?: number[] + int32s?: number[] + int64s?: bigint[] + uint32s?: number[] + uint64s?: bigint[] + sint32s?: number[] + sint64s?: bigint[] + fixed32s?: number[] + fixed64s?: bigint[] + sfixed32s?: number[] + sfixed64s?: bigint[] + bools?: boolean[] +} + export namespace PackedTypes { - let _codec: Codec + let _codec: Codec - export const codec = (): Codec => { + export const codec = (): Codec => { if (_codec == null) { - _codec = message((obj, w, opts = {}) => { + _codec = message((obj, w, opts = {}) => { if (opts.lengthDelimited !== false) { w.fork() } @@ -1725,7 +1762,7 @@ export namespace PackedTypes { value: boolean } - export function encode (obj: Partial): Uint8Array { + export function encode (obj: PackedTypesInput): Uint8Array { return encodeMessage(obj, PackedTypes.codec()) } @@ -1754,105 +1791,173 @@ export interface ExpandedTypes { bools: boolean[] } +export interface ExpandedTypesInput { + doubles?: number[] + floats?: number[] + int32s?: number[] + int64s?: bigint[] + uint32s?: number[] + uint64s?: bigint[] + sint32s?: number[] + sint64s?: bigint[] + fixed32s?: number[] + fixed64s?: bigint[] + sfixed32s?: number[] + sfixed64s?: bigint[] + bools?: boolean[] +} + export namespace ExpandedTypes { - let _codec: Codec + let _codec: Codec - export const codec = (): Codec => { + export const codec = (): Codec => { if (_codec == null) { - _codec = message((obj, w, opts = {}) => { + _codec = message((obj, w, opts = {}) => { if (opts.lengthDelimited !== false) { w.fork() } if (obj.doubles != null && obj.doubles.length > 0) { + w.uint32(10) + w.fork() + for (const value of obj.doubles) { - w.uint32(9) w.double(value) } + + w.ldelim() } if (obj.floats != null && obj.floats.length > 0) { + w.uint32(18) + w.fork() + for (const value of obj.floats) { - w.uint32(21) w.float(value) } + + w.ldelim() } if (obj.int32s != null && obj.int32s.length > 0) { + w.uint32(26) + w.fork() + for (const value of obj.int32s) { - w.uint32(24) w.int32(value) } + + w.ldelim() } if (obj.int64s != null && obj.int64s.length > 0) { + w.uint32(34) + w.fork() + for (const value of obj.int64s) { - w.uint32(32) w.int64(value) } + + w.ldelim() } if (obj.uint32s != null && obj.uint32s.length > 0) { + w.uint32(42) + w.fork() + for (const value of obj.uint32s) { - w.uint32(40) w.uint32(value) } + + w.ldelim() } if (obj.uint64s != null && obj.uint64s.length > 0) { + w.uint32(50) + w.fork() + for (const value of obj.uint64s) { - w.uint32(48) w.uint64(value) } + + w.ldelim() } if (obj.sint32s != null && obj.sint32s.length > 0) { + w.uint32(58) + w.fork() + for (const value of obj.sint32s) { - w.uint32(56) w.sint32(value) } + + w.ldelim() } if (obj.sint64s != null && obj.sint64s.length > 0) { + w.uint32(66) + w.fork() + for (const value of obj.sint64s) { - w.uint32(64) w.sint64(value) } + + w.ldelim() } if (obj.fixed32s != null && obj.fixed32s.length > 0) { + w.uint32(74) + w.fork() + for (const value of obj.fixed32s) { - w.uint32(77) w.fixed32(value) } + + w.ldelim() } if (obj.fixed64s != null && obj.fixed64s.length > 0) { + w.uint32(82) + w.fork() + for (const value of obj.fixed64s) { - w.uint32(81) w.fixed64(value) } + + w.ldelim() } if (obj.sfixed32s != null && obj.sfixed32s.length > 0) { + w.uint32(90) + w.fork() + for (const value of obj.sfixed32s) { - w.uint32(93) w.sfixed32(value) } + + w.ldelim() } if (obj.sfixed64s != null && obj.sfixed64s.length > 0) { + w.uint32(98) + w.fork() + for (const value of obj.sfixed64s) { - w.uint32(97) w.sfixed64(value) } + + w.ldelim() } if (obj.bools != null && obj.bools.length > 0) { + w.uint32(106) + w.fork() + for (const value of obj.bools) { - w.uint32(104) w.bool(value) } + + w.ldelim() } if (opts.lengthDelimited !== false) { @@ -1882,107 +1987,185 @@ export namespace ExpandedTypes { switch (tag >>> 3) { case 1: { - if (opts.limits?.doubles != null && obj.doubles.length === opts.limits.doubles) { - throw new MaxLengthError('Decode error - repeated field "doubles" had too many elements') + const b = r.bytes() + const r2 = reader(b) + + while (r2.pos < r2.len) { + if (opts.limits?.doubles != null && obj.doubles.length === opts.limits.doubles) { + throw new MaxLengthError('Decode error - repeated field "doubles" had too many elements') + } + + obj.doubles.push(r2.double()) } - obj.doubles.push(r.double()) break } case 2: { - if (opts.limits?.floats != null && obj.floats.length === opts.limits.floats) { - throw new MaxLengthError('Decode error - repeated field "floats" had too many elements') + const b = r.bytes() + const r2 = reader(b) + + while (r2.pos < r2.len) { + if (opts.limits?.floats != null && obj.floats.length === opts.limits.floats) { + throw new MaxLengthError('Decode error - repeated field "floats" had too many elements') + } + + obj.floats.push(r2.float()) } - obj.floats.push(r.float()) break } case 3: { - if (opts.limits?.int32s != null && obj.int32s.length === opts.limits.int32s) { - throw new MaxLengthError('Decode error - repeated field "int32s" had too many elements') + const b = r.bytes() + const r2 = reader(b) + + while (r2.pos < r2.len) { + if (opts.limits?.int32s != null && obj.int32s.length === opts.limits.int32s) { + throw new MaxLengthError('Decode error - repeated field "int32s" had too many elements') + } + + obj.int32s.push(r2.int32()) } - obj.int32s.push(r.int32()) break } case 4: { - if (opts.limits?.int64s != null && obj.int64s.length === opts.limits.int64s) { - throw new MaxLengthError('Decode error - repeated field "int64s" had too many elements') + const b = r.bytes() + const r2 = reader(b) + + while (r2.pos < r2.len) { + if (opts.limits?.int64s != null && obj.int64s.length === opts.limits.int64s) { + throw new MaxLengthError('Decode error - repeated field "int64s" had too many elements') + } + + obj.int64s.push(r2.int64()) } - obj.int64s.push(r.int64()) break } case 5: { - if (opts.limits?.uint32s != null && obj.uint32s.length === opts.limits.uint32s) { - throw new MaxLengthError('Decode error - repeated field "uint32s" had too many elements') + const b = r.bytes() + const r2 = reader(b) + + while (r2.pos < r2.len) { + if (opts.limits?.uint32s != null && obj.uint32s.length === opts.limits.uint32s) { + throw new MaxLengthError('Decode error - repeated field "uint32s" had too many elements') + } + + obj.uint32s.push(r2.uint32()) } - obj.uint32s.push(r.uint32()) break } case 6: { - if (opts.limits?.uint64s != null && obj.uint64s.length === opts.limits.uint64s) { - throw new MaxLengthError('Decode error - repeated field "uint64s" had too many elements') + const b = r.bytes() + const r2 = reader(b) + + while (r2.pos < r2.len) { + if (opts.limits?.uint64s != null && obj.uint64s.length === opts.limits.uint64s) { + throw new MaxLengthError('Decode error - repeated field "uint64s" had too many elements') + } + + obj.uint64s.push(r2.uint64()) } - obj.uint64s.push(r.uint64()) break } case 7: { - if (opts.limits?.sint32s != null && obj.sint32s.length === opts.limits.sint32s) { - throw new MaxLengthError('Decode error - repeated field "sint32s" had too many elements') + const b = r.bytes() + const r2 = reader(b) + + while (r2.pos < r2.len) { + if (opts.limits?.sint32s != null && obj.sint32s.length === opts.limits.sint32s) { + throw new MaxLengthError('Decode error - repeated field "sint32s" had too many elements') + } + + obj.sint32s.push(r2.sint32()) } - obj.sint32s.push(r.sint32()) break } case 8: { - if (opts.limits?.sint64s != null && obj.sint64s.length === opts.limits.sint64s) { - throw new MaxLengthError('Decode error - repeated field "sint64s" had too many elements') + const b = r.bytes() + const r2 = reader(b) + + while (r2.pos < r2.len) { + if (opts.limits?.sint64s != null && obj.sint64s.length === opts.limits.sint64s) { + throw new MaxLengthError('Decode error - repeated field "sint64s" had too many elements') + } + + obj.sint64s.push(r2.sint64()) } - obj.sint64s.push(r.sint64()) break } case 9: { - if (opts.limits?.fixed32s != null && obj.fixed32s.length === opts.limits.fixed32s) { - throw new MaxLengthError('Decode error - repeated field "fixed32s" had too many elements') + const b = r.bytes() + const r2 = reader(b) + + while (r2.pos < r2.len) { + if (opts.limits?.fixed32s != null && obj.fixed32s.length === opts.limits.fixed32s) { + throw new MaxLengthError('Decode error - repeated field "fixed32s" had too many elements') + } + + obj.fixed32s.push(r2.fixed32()) } - obj.fixed32s.push(r.fixed32()) break } case 10: { - if (opts.limits?.fixed64s != null && obj.fixed64s.length === opts.limits.fixed64s) { - throw new MaxLengthError('Decode error - repeated field "fixed64s" had too many elements') + const b = r.bytes() + const r2 = reader(b) + + while (r2.pos < r2.len) { + if (opts.limits?.fixed64s != null && obj.fixed64s.length === opts.limits.fixed64s) { + throw new MaxLengthError('Decode error - repeated field "fixed64s" had too many elements') + } + + obj.fixed64s.push(r2.fixed64()) } - obj.fixed64s.push(r.fixed64()) break } case 11: { - if (opts.limits?.sfixed32s != null && obj.sfixed32s.length === opts.limits.sfixed32s) { - throw new MaxLengthError('Decode error - repeated field "sfixed32s" had too many elements') + const b = r.bytes() + const r2 = reader(b) + + while (r2.pos < r2.len) { + if (opts.limits?.sfixed32s != null && obj.sfixed32s.length === opts.limits.sfixed32s) { + throw new MaxLengthError('Decode error - repeated field "sfixed32s" had too many elements') + } + + obj.sfixed32s.push(r2.sfixed32()) } - obj.sfixed32s.push(r.sfixed32()) break } case 12: { - if (opts.limits?.sfixed64s != null && obj.sfixed64s.length === opts.limits.sfixed64s) { - throw new MaxLengthError('Decode error - repeated field "sfixed64s" had too many elements') + const b = r.bytes() + const r2 = reader(b) + + while (r2.pos < r2.len) { + if (opts.limits?.sfixed64s != null && obj.sfixed64s.length === opts.limits.sfixed64s) { + throw new MaxLengthError('Decode error - repeated field "sfixed64s" had too many elements') + } + + obj.sfixed64s.push(r2.sfixed64()) } - obj.sfixed64s.push(r.sfixed64()) break } case 13: { - if (opts.limits?.bools != null && obj.bools.length === opts.limits.bools) { - throw new MaxLengthError('Decode error - repeated field "bools" had too many elements') + const b = r.bytes() + const r2 = reader(b) + + while (r2.pos < r2.len) { + if (opts.limits?.bools != null && obj.bools.length === opts.limits.bools) { + throw new MaxLengthError('Decode error - repeated field "bools" had too many elements') + } + + obj.bools.push(r2.bool()) } - obj.bools.push(r.bool()) break } default: { @@ -2025,197 +2208,262 @@ export namespace ExpandedTypes { switch (tag >>> 3) { case 1: { - if (opts.limits?.doubles != null && obj.doubles === opts.limits.doubles) { - throw new MaxLengthError('Streaming decode error - repeated field "doubles" had too many elements') - } + const b = r.bytes() + const r2 = reader(b) - yield { - field: `${prefix}doubles[]`, - index: obj.doubles, - value: r.double() - } + while (r2.pos < r2.len) { + if (opts.limits?.doubles != null && obj.doubles === opts.limits.doubles) { + throw new MaxLengthError('Streaming decode error - repeated field "doubles" had too many elements') + } - obj.doubles++ + yield { + field: `${prefix}doubles[]`, + index: obj.doubles, + value: r2.double() + } + + obj.doubles++ + } break } case 2: { - if (opts.limits?.floats != null && obj.floats === opts.limits.floats) { - throw new MaxLengthError('Streaming decode error - repeated field "floats" had too many elements') - } + const b = r.bytes() + const r2 = reader(b) - yield { - field: `${prefix}floats[]`, - index: obj.floats, - value: r.float() - } + while (r2.pos < r2.len) { + if (opts.limits?.floats != null && obj.floats === opts.limits.floats) { + throw new MaxLengthError('Streaming decode error - repeated field "floats" had too many elements') + } - obj.floats++ + yield { + field: `${prefix}floats[]`, + index: obj.floats, + value: r2.float() + } + + obj.floats++ + } break } case 3: { - if (opts.limits?.int32s != null && obj.int32s === opts.limits.int32s) { - throw new MaxLengthError('Streaming decode error - repeated field "int32s" had too many elements') - } + const b = r.bytes() + const r2 = reader(b) - yield { - field: `${prefix}int32s[]`, - index: obj.int32s, - value: r.int32() - } + while (r2.pos < r2.len) { + if (opts.limits?.int32s != null && obj.int32s === opts.limits.int32s) { + throw new MaxLengthError('Streaming decode error - repeated field "int32s" had too many elements') + } - obj.int32s++ + yield { + field: `${prefix}int32s[]`, + index: obj.int32s, + value: r2.int32() + } + + obj.int32s++ + } break } case 4: { - if (opts.limits?.int64s != null && obj.int64s === opts.limits.int64s) { - throw new MaxLengthError('Streaming decode error - repeated field "int64s" had too many elements') - } + const b = r.bytes() + const r2 = reader(b) - yield { - field: `${prefix}int64s[]`, - index: obj.int64s, - value: r.int64() - } + while (r2.pos < r2.len) { + if (opts.limits?.int64s != null && obj.int64s === opts.limits.int64s) { + throw new MaxLengthError('Streaming decode error - repeated field "int64s" had too many elements') + } - obj.int64s++ + yield { + field: `${prefix}int64s[]`, + index: obj.int64s, + value: r2.int64() + } + + obj.int64s++ + } break } case 5: { - if (opts.limits?.uint32s != null && obj.uint32s === opts.limits.uint32s) { - throw new MaxLengthError('Streaming decode error - repeated field "uint32s" had too many elements') - } + const b = r.bytes() + const r2 = reader(b) - yield { - field: `${prefix}uint32s[]`, - index: obj.uint32s, - value: r.uint32() - } + while (r2.pos < r2.len) { + if (opts.limits?.uint32s != null && obj.uint32s === opts.limits.uint32s) { + throw new MaxLengthError('Streaming decode error - repeated field "uint32s" had too many elements') + } - obj.uint32s++ + yield { + field: `${prefix}uint32s[]`, + index: obj.uint32s, + value: r2.uint32() + } + + obj.uint32s++ + } break } case 6: { - if (opts.limits?.uint64s != null && obj.uint64s === opts.limits.uint64s) { - throw new MaxLengthError('Streaming decode error - repeated field "uint64s" had too many elements') - } + const b = r.bytes() + const r2 = reader(b) - yield { - field: `${prefix}uint64s[]`, - index: obj.uint64s, - value: r.uint64() - } + while (r2.pos < r2.len) { + if (opts.limits?.uint64s != null && obj.uint64s === opts.limits.uint64s) { + throw new MaxLengthError('Streaming decode error - repeated field "uint64s" had too many elements') + } - obj.uint64s++ + yield { + field: `${prefix}uint64s[]`, + index: obj.uint64s, + value: r2.uint64() + } + + obj.uint64s++ + } break } case 7: { - if (opts.limits?.sint32s != null && obj.sint32s === opts.limits.sint32s) { - throw new MaxLengthError('Streaming decode error - repeated field "sint32s" had too many elements') - } + const b = r.bytes() + const r2 = reader(b) - yield { - field: `${prefix}sint32s[]`, - index: obj.sint32s, - value: r.sint32() - } + while (r2.pos < r2.len) { + if (opts.limits?.sint32s != null && obj.sint32s === opts.limits.sint32s) { + throw new MaxLengthError('Streaming decode error - repeated field "sint32s" had too many elements') + } - obj.sint32s++ + yield { + field: `${prefix}sint32s[]`, + index: obj.sint32s, + value: r2.sint32() + } + + obj.sint32s++ + } break } case 8: { - if (opts.limits?.sint64s != null && obj.sint64s === opts.limits.sint64s) { - throw new MaxLengthError('Streaming decode error - repeated field "sint64s" had too many elements') - } + const b = r.bytes() + const r2 = reader(b) - yield { - field: `${prefix}sint64s[]`, - index: obj.sint64s, - value: r.sint64() - } + while (r2.pos < r2.len) { + if (opts.limits?.sint64s != null && obj.sint64s === opts.limits.sint64s) { + throw new MaxLengthError('Streaming decode error - repeated field "sint64s" had too many elements') + } - obj.sint64s++ + yield { + field: `${prefix}sint64s[]`, + index: obj.sint64s, + value: r2.sint64() + } + + obj.sint64s++ + } break } case 9: { - if (opts.limits?.fixed32s != null && obj.fixed32s === opts.limits.fixed32s) { - throw new MaxLengthError('Streaming decode error - repeated field "fixed32s" had too many elements') - } + const b = r.bytes() + const r2 = reader(b) - yield { - field: `${prefix}fixed32s[]`, - index: obj.fixed32s, - value: r.fixed32() - } + while (r2.pos < r2.len) { + if (opts.limits?.fixed32s != null && obj.fixed32s === opts.limits.fixed32s) { + throw new MaxLengthError('Streaming decode error - repeated field "fixed32s" had too many elements') + } - obj.fixed32s++ + yield { + field: `${prefix}fixed32s[]`, + index: obj.fixed32s, + value: r2.fixed32() + } + + obj.fixed32s++ + } break } case 10: { - if (opts.limits?.fixed64s != null && obj.fixed64s === opts.limits.fixed64s) { - throw new MaxLengthError('Streaming decode error - repeated field "fixed64s" had too many elements') - } + const b = r.bytes() + const r2 = reader(b) - yield { - field: `${prefix}fixed64s[]`, - index: obj.fixed64s, - value: r.fixed64() - } + while (r2.pos < r2.len) { + if (opts.limits?.fixed64s != null && obj.fixed64s === opts.limits.fixed64s) { + throw new MaxLengthError('Streaming decode error - repeated field "fixed64s" had too many elements') + } - obj.fixed64s++ + yield { + field: `${prefix}fixed64s[]`, + index: obj.fixed64s, + value: r2.fixed64() + } + + obj.fixed64s++ + } break } case 11: { - if (opts.limits?.sfixed32s != null && obj.sfixed32s === opts.limits.sfixed32s) { - throw new MaxLengthError('Streaming decode error - repeated field "sfixed32s" had too many elements') - } + const b = r.bytes() + const r2 = reader(b) - yield { - field: `${prefix}sfixed32s[]`, - index: obj.sfixed32s, - value: r.sfixed32() - } + while (r2.pos < r2.len) { + if (opts.limits?.sfixed32s != null && obj.sfixed32s === opts.limits.sfixed32s) { + throw new MaxLengthError('Streaming decode error - repeated field "sfixed32s" had too many elements') + } - obj.sfixed32s++ + yield { + field: `${prefix}sfixed32s[]`, + index: obj.sfixed32s, + value: r2.sfixed32() + } + + obj.sfixed32s++ + } break } case 12: { - if (opts.limits?.sfixed64s != null && obj.sfixed64s === opts.limits.sfixed64s) { - throw new MaxLengthError('Streaming decode error - repeated field "sfixed64s" had too many elements') - } + const b = r.bytes() + const r2 = reader(b) - yield { - field: `${prefix}sfixed64s[]`, - index: obj.sfixed64s, - value: r.sfixed64() - } + while (r2.pos < r2.len) { + if (opts.limits?.sfixed64s != null && obj.sfixed64s === opts.limits.sfixed64s) { + throw new MaxLengthError('Streaming decode error - repeated field "sfixed64s" had too many elements') + } - obj.sfixed64s++ + yield { + field: `${prefix}sfixed64s[]`, + index: obj.sfixed64s, + value: r2.sfixed64() + } + + obj.sfixed64s++ + } break } case 13: { - if (opts.limits?.bools != null && obj.bools === opts.limits.bools) { - throw new MaxLengthError('Streaming decode error - repeated field "bools" had too many elements') - } + const b = r.bytes() + const r2 = reader(b) - yield { - field: `${prefix}bools[]`, - index: obj.bools, - value: r.bool() - } + while (r2.pos < r2.len) { + if (opts.limits?.bools != null && obj.bools === opts.limits.bools) { + throw new MaxLengthError('Streaming decode error - repeated field "bools" had too many elements') + } - obj.bools++ + yield { + field: `${prefix}bools[]`, + index: obj.bools, + value: r2.bool() + } + + obj.bools++ + } break } @@ -2317,7 +2565,7 @@ export namespace ExpandedTypes { value: boolean } - export function encode (obj: Partial): Uint8Array { + export function encode (obj: ExpandedTypesInput): Uint8Array { return encodeMessage(obj, ExpandedTypes.codec()) } @@ -2346,12 +2594,28 @@ export interface NewOptionPackedTypes { bools: boolean[] } +export interface NewOptionPackedTypesInput { + doubles?: number[] + floats?: number[] + int32s?: number[] + int64s?: bigint[] + uint32s?: number[] + uint64s?: bigint[] + sint32s?: number[] + sint64s?: bigint[] + fixed32s?: number[] + fixed64s?: bigint[] + sfixed32s?: number[] + sfixed64s?: bigint[] + bools?: boolean[] +} + export namespace NewOptionPackedTypes { - let _codec: Codec + let _codec: Codec - export const codec = (): Codec => { + export const codec = (): Codec => { if (_codec == null) { - _codec = message((obj, w, opts = {}) => { + _codec = message((obj, w, opts = {}) => { if (opts.lengthDelimited !== false) { w.fork() } @@ -3104,7 +3368,7 @@ export namespace NewOptionPackedTypes { value: boolean } - export function encode (obj: Partial): Uint8Array { + export function encode (obj: NewOptionPackedTypesInput): Uint8Array { return encodeMessage(obj, NewOptionPackedTypes.codec()) } @@ -3133,12 +3397,28 @@ export interface NewOptionExpandedTypes { bools: boolean[] } +export interface NewOptionExpandedTypesInput { + doubles?: number[] + floats?: number[] + int32s?: number[] + int64s?: bigint[] + uint32s?: number[] + uint64s?: bigint[] + sint32s?: number[] + sint64s?: bigint[] + fixed32s?: number[] + fixed64s?: bigint[] + sfixed32s?: number[] + sfixed64s?: bigint[] + bools?: boolean[] +} + export namespace NewOptionExpandedTypes { - let _codec: Codec + let _codec: Codec - export const codec = (): Codec => { + export const codec = (): Codec => { if (_codec == null) { - _codec = message((obj, w, opts = {}) => { + _codec = message((obj, w, opts = {}) => { if (opts.lengthDelimited !== false) { w.fork() } @@ -3696,7 +3976,7 @@ export namespace NewOptionExpandedTypes { value: boolean } - export function encode (obj: Partial): Uint8Array { + export function encode (obj: NewOptionExpandedTypesInput): Uint8Array { return encodeMessage(obj, NewOptionExpandedTypes.codec()) } diff --git a/packages/protons/test/packed.spec.ts b/packages/protons/test/packed.spec.ts index aef6427..996c6f9 100644 --- a/packages/protons/test/packed.spec.ts +++ b/packages/protons/test/packed.spec.ts @@ -155,42 +155,22 @@ describe('packed', () => { it('should respect global options', () => { expect(uint8ArrayToString(GlobalPacked.encode({ - expanded: [1, 1], - packedOldOption: [], - expandedOldOption: [], - packedNewOption: [], - expandedNewOption: [] + expanded: [1, 1] }), 'base16')).to.equal('08010801', 'file-level repeated-field-encoding set to expanded ignored') expect(uint8ArrayToString(GlobalPacked.encode({ - expanded: [], - packedOldOption: [1, 1], - expandedOldOption: [], - packedNewOption: [], - expandedNewOption: [] + packedOldOption: [1, 1] }), 'base16')).to.equal('10011001', 'old field-level repeated-field-encoding set to packed ignored') expect(uint8ArrayToString(GlobalPacked.encode({ - expanded: [], - packedOldOption: [], - expandedOldOption: [1, 1], - packedNewOption: [], - expandedNewOption: [] + expandedOldOption: [1, 1] }), 'base16')).to.equal('18011801', 'old field-level repeated-field-encoding set to expanded ignored') expect(uint8ArrayToString(GlobalPacked.encode({ - expanded: [], - packedOldOption: [], - expandedOldOption: [], - packedNewOption: [1, 1], - expandedNewOption: [] + packedNewOption: [1, 1] }), 'base16')).to.equal('22020101', 'new field-level repeated-field-encoding set to packed ignored') expect(uint8ArrayToString(GlobalPacked.encode({ - expanded: [], - packedOldOption: [], - expandedOldOption: [], - packedNewOption: [], expandedNewOption: [1, 1] }), 'base16')).to.equal('28012801', 'new field-level repeated-field-encoding set to expanded ignored') From 5f0be23ac53bcd6b1b5c90cc41699e5e09f82e42 Mon Sep 17 00:00:00 2001 From: achingbrain Date: Fri, 18 Sep 2026 10:02:26 +0300 Subject: [PATCH 4/6] chore: fix up proto2 --- packages/protons/src/fields/array-field.ts | 29 +- packages/protons/src/types/message.ts | 2 + .../protons/test/fixtures/packed-proto2.proto | 49 + .../protons/test/fixtures/packed-proto2.ts | 2022 +++++++++++++++++ packages/protons/test/fixtures/packed.proto | 36 +- packages/protons/test/fixtures/packed.ts | 1714 +------------- packages/protons/test/packed.spec.ts | 171 +- 7 files changed, 2250 insertions(+), 1773 deletions(-) create mode 100644 packages/protons/test/fixtures/packed-proto2.proto create mode 100644 packages/protons/test/fixtures/packed-proto2.ts diff --git a/packages/protons/src/fields/array-field.ts b/packages/protons/src/fields/array-field.ts index 0c9d6a4..31051d4 100644 --- a/packages/protons/src/fields/array-field.ts +++ b/packages/protons/src/fields/array-field.ts @@ -28,6 +28,9 @@ const PACKABLE_TYPES = [ 'bool' ] +/** + * Detect proto3 (and later) expanded field override + */ function useExpandedEncoding (fieldOptions?: Record, globalOptions?: Record): boolean { if (fieldOptions?.features?.repeated_field_encoding === 'EXPANDED') { return true @@ -48,6 +51,13 @@ function useExpandedEncoding (fieldOptions?: Record, globalOptions? return false } +/** + * Detect proto2 packed field override + */ +function usePackedEncoding (fieldOptions?: Record, globalOptions?: Record): boolean { + return fieldOptions?.packed === true +} + export class ArrayField extends Field { private lengthLimit?: number private packed: boolean @@ -60,12 +70,21 @@ export class ArrayField extends Field { const type = parent.findType(this.type).pbType const supportsPacked = PACKABLE_TYPES.indexOf(type) !== -1 - // the default from protobuf3 onwards - this.packed = supportsPacked - - // check user overrides for field encoding - if (useExpandedEncoding(def.options, parent.def.options)) { + if (parent.def.edition === 'proto2') { this.packed = false + + // check user overrides for field encoding + if (usePackedEncoding(def.options, parent.def.options)) { + this.packed = true + } + } else { + // the default from protobuf3 onwards + this.packed = supportsPacked + + // check user overrides for field encoding + if (useExpandedEncoding(def.options, parent.def.options)) { + this.packed = false + } } if (this.packed && !supportsPacked) { diff --git a/packages/protons/src/types/message.ts b/packages/protons/src/types/message.ts index be377b0..66b7e43 100644 --- a/packages/protons/src/types/message.ts +++ b/packages/protons/src/types/message.ts @@ -27,6 +27,7 @@ function camelize (input: string): string { } export interface MessageDef { + edition: string options?: Record fields?: Record oneofs?: Record @@ -69,6 +70,7 @@ export class Message implements Type { const mapEntryType = `${this.pbType}$${fieldName}Entry` def.nested[mapEntryType] = { + edition: def.edition, fields: { key: { type: fieldDef.keyType, diff --git a/packages/protons/test/fixtures/packed-proto2.proto b/packages/protons/test/fixtures/packed-proto2.proto new file mode 100644 index 0000000..d1a5dff --- /dev/null +++ b/packages/protons/test/fixtures/packed-proto2.proto @@ -0,0 +1,49 @@ +syntax = "proto2"; + +message Proto2DefaultPackedTypes { + repeated double doubles = 1; + repeated float floats = 2; + repeated int32 int32s = 3; + repeated int64 int64s = 4; + repeated uint32 uint32s = 5; + repeated uint64 uint64s = 6; + repeated sint32 sint32s = 7; + repeated sint64 sint64s = 8; + repeated fixed32 fixed32s = 9; + repeated fixed64 fixed64s = 10; + repeated sfixed32 sfixed32s = 11; + repeated sfixed64 sfixed64s = 12; + repeated bool bools = 13; +} + +message Proto2PackedTypes { + repeated double doubles = 1 [packed=true]; + repeated float floats = 2 [packed=true]; + repeated int32 int32s = 3 [packed=true]; + repeated int64 int64s = 4 [packed=true]; + repeated uint32 uint32s = 5 [packed=true]; + repeated uint64 uint64s = 6 [packed=true]; + repeated sint32 sint32s = 7 [packed=true]; + repeated sint64 sint64s = 8 [packed=true]; + repeated fixed32 fixed32s = 9 [packed=true]; + repeated fixed64 fixed64s = 10 [packed=true]; + repeated sfixed32 sfixed32s = 11 [packed=true]; + repeated sfixed64 sfixed64s = 12 [packed=true]; + repeated bool bools = 13 [packed=true]; +} + +message Proto2ExpandedTypes { + repeated double doubles = 1 [packed=false]; + repeated float floats = 2 [packed=false]; + repeated int32 int32s = 3 [packed=false]; + repeated int64 int64s = 4 [packed=false]; + repeated uint32 uint32s = 5 [packed=false]; + repeated uint64 uint64s = 6 [packed=false]; + repeated sint32 sint32s = 7 [packed=false]; + repeated sint64 sint64s = 8 [packed=false]; + repeated fixed32 fixed32s = 9 [packed=false]; + repeated fixed64 fixed64s = 10 [packed=false]; + repeated sfixed32 sfixed32s = 11 [packed=false]; + repeated sfixed64 sfixed64s = 12 [packed=false]; + repeated bool bools = 13 [packed=false]; +} diff --git a/packages/protons/test/fixtures/packed-proto2.ts b/packages/protons/test/fixtures/packed-proto2.ts new file mode 100644 index 0000000..b31c690 --- /dev/null +++ b/packages/protons/test/fixtures/packed-proto2.ts @@ -0,0 +1,2022 @@ +import { decodeMessage, encodeMessage, MaxLengthError, message, reader, streamMessage } from 'protons-runtime' +import type { Codec, DecodeOptions } from 'protons-runtime' +import type { Uint8ArrayList } from 'uint8arraylist' + +export interface Proto2DefaultPackedTypes { + doubles: number[] + floats: number[] + int32s: number[] + int64s: bigint[] + uint32s: number[] + uint64s: bigint[] + sint32s: number[] + sint64s: bigint[] + fixed32s: number[] + fixed64s: bigint[] + sfixed32s: number[] + sfixed64s: bigint[] + bools: boolean[] +} + +export interface Proto2DefaultPackedTypesInput { + doubles?: number[] + floats?: number[] + int32s?: number[] + int64s?: bigint[] + uint32s?: number[] + uint64s?: bigint[] + sint32s?: number[] + sint64s?: bigint[] + fixed32s?: number[] + fixed64s?: bigint[] + sfixed32s?: number[] + sfixed64s?: bigint[] + bools?: boolean[] +} + +export namespace Proto2DefaultPackedTypes { + let _codec: Codec + + export const codec = (): Codec => { + if (_codec == null) { + _codec = message((obj, w, opts = {}) => { + if (opts.lengthDelimited !== false) { + w.fork() + } + + if (obj.doubles != null && obj.doubles.length > 0) { + for (const value of obj.doubles) { + w.uint32(9) + w.double(value) + } + } + + if (obj.floats != null && obj.floats.length > 0) { + for (const value of obj.floats) { + w.uint32(21) + w.float(value) + } + } + + if (obj.int32s != null && obj.int32s.length > 0) { + for (const value of obj.int32s) { + w.uint32(24) + w.int32(value) + } + } + + if (obj.int64s != null && obj.int64s.length > 0) { + for (const value of obj.int64s) { + w.uint32(32) + w.int64(value) + } + } + + if (obj.uint32s != null && obj.uint32s.length > 0) { + for (const value of obj.uint32s) { + w.uint32(40) + w.uint32(value) + } + } + + if (obj.uint64s != null && obj.uint64s.length > 0) { + for (const value of obj.uint64s) { + w.uint32(48) + w.uint64(value) + } + } + + if (obj.sint32s != null && obj.sint32s.length > 0) { + for (const value of obj.sint32s) { + w.uint32(56) + w.sint32(value) + } + } + + if (obj.sint64s != null && obj.sint64s.length > 0) { + for (const value of obj.sint64s) { + w.uint32(64) + w.sint64(value) + } + } + + if (obj.fixed32s != null && obj.fixed32s.length > 0) { + for (const value of obj.fixed32s) { + w.uint32(77) + w.fixed32(value) + } + } + + if (obj.fixed64s != null && obj.fixed64s.length > 0) { + for (const value of obj.fixed64s) { + w.uint32(81) + w.fixed64(value) + } + } + + if (obj.sfixed32s != null && obj.sfixed32s.length > 0) { + for (const value of obj.sfixed32s) { + w.uint32(93) + w.sfixed32(value) + } + } + + if (obj.sfixed64s != null && obj.sfixed64s.length > 0) { + for (const value of obj.sfixed64s) { + w.uint32(97) + w.sfixed64(value) + } + } + + if (obj.bools != null && obj.bools.length > 0) { + for (const value of obj.bools) { + w.uint32(104) + w.bool(value) + } + } + + if (opts.lengthDelimited !== false) { + w.ldelim() + } + }, (r, length, opts = {}) => { + const obj: any = { + doubles: [], + floats: [], + int32s: [], + int64s: [], + uint32s: [], + uint64s: [], + sint32s: [], + sint64s: [], + fixed32s: [], + fixed64s: [], + sfixed32s: [], + sfixed64s: [], + bools: [] + } + + const end = length == null ? r.len : r.pos + length + + while (r.pos < end) { + const tag = r.uint32() + + switch (tag >>> 3) { + case 1: { + if (opts.limits?.doubles != null && obj.doubles.length === opts.limits.doubles) { + throw new MaxLengthError('Decode error - repeated field "doubles" had too many elements') + } + + obj.doubles.push(r.double()) + break + } + case 2: { + if (opts.limits?.floats != null && obj.floats.length === opts.limits.floats) { + throw new MaxLengthError('Decode error - repeated field "floats" had too many elements') + } + + obj.floats.push(r.float()) + break + } + case 3: { + if (opts.limits?.int32s != null && obj.int32s.length === opts.limits.int32s) { + throw new MaxLengthError('Decode error - repeated field "int32s" had too many elements') + } + + obj.int32s.push(r.int32()) + break + } + case 4: { + if (opts.limits?.int64s != null && obj.int64s.length === opts.limits.int64s) { + throw new MaxLengthError('Decode error - repeated field "int64s" had too many elements') + } + + obj.int64s.push(r.int64()) + break + } + case 5: { + if (opts.limits?.uint32s != null && obj.uint32s.length === opts.limits.uint32s) { + throw new MaxLengthError('Decode error - repeated field "uint32s" had too many elements') + } + + obj.uint32s.push(r.uint32()) + break + } + case 6: { + if (opts.limits?.uint64s != null && obj.uint64s.length === opts.limits.uint64s) { + throw new MaxLengthError('Decode error - repeated field "uint64s" had too many elements') + } + + obj.uint64s.push(r.uint64()) + break + } + case 7: { + if (opts.limits?.sint32s != null && obj.sint32s.length === opts.limits.sint32s) { + throw new MaxLengthError('Decode error - repeated field "sint32s" had too many elements') + } + + obj.sint32s.push(r.sint32()) + break + } + case 8: { + if (opts.limits?.sint64s != null && obj.sint64s.length === opts.limits.sint64s) { + throw new MaxLengthError('Decode error - repeated field "sint64s" had too many elements') + } + + obj.sint64s.push(r.sint64()) + break + } + case 9: { + if (opts.limits?.fixed32s != null && obj.fixed32s.length === opts.limits.fixed32s) { + throw new MaxLengthError('Decode error - repeated field "fixed32s" had too many elements') + } + + obj.fixed32s.push(r.fixed32()) + break + } + case 10: { + if (opts.limits?.fixed64s != null && obj.fixed64s.length === opts.limits.fixed64s) { + throw new MaxLengthError('Decode error - repeated field "fixed64s" had too many elements') + } + + obj.fixed64s.push(r.fixed64()) + break + } + case 11: { + if (opts.limits?.sfixed32s != null && obj.sfixed32s.length === opts.limits.sfixed32s) { + throw new MaxLengthError('Decode error - repeated field "sfixed32s" had too many elements') + } + + obj.sfixed32s.push(r.sfixed32()) + break + } + case 12: { + if (opts.limits?.sfixed64s != null && obj.sfixed64s.length === opts.limits.sfixed64s) { + throw new MaxLengthError('Decode error - repeated field "sfixed64s" had too many elements') + } + + obj.sfixed64s.push(r.sfixed64()) + break + } + case 13: { + if (opts.limits?.bools != null && obj.bools.length === opts.limits.bools) { + throw new MaxLengthError('Decode error - repeated field "bools" had too many elements') + } + + obj.bools.push(r.bool()) + break + } + default: { + r.skipType(tag & 7) + break + } + } + } + + return obj + }, function * (r, length, prefix, opts = {}) { + const obj = { + doubles: 0, + floats: 0, + int32s: 0, + int64s: 0, + uint32s: 0, + uint64s: 0, + sint32s: 0, + sint64s: 0, + fixed32s: 0, + fixed64s: 0, + sfixed32s: 0, + sfixed64s: 0, + bools: 0 + } + + const end = length == null ? r.len : r.pos + length + + if (prefix !== '.') { + yield { + field: prefix.endsWith('.') ? prefix.substring(0, prefix.length - 1) : prefix, + type: 'start', + message: 'Proto2DefaultPackedTypes' + } + } + + while (r.pos < end) { + const tag = r.uint32() + + switch (tag >>> 3) { + case 1: { + if (opts.limits?.doubles != null && obj.doubles === opts.limits.doubles) { + throw new MaxLengthError('Streaming decode error - repeated field "doubles" had too many elements') + } + + yield { + field: `${prefix}doubles[]`, + index: obj.doubles, + value: r.double() + } + + obj.doubles++ + + break + } + case 2: { + if (opts.limits?.floats != null && obj.floats === opts.limits.floats) { + throw new MaxLengthError('Streaming decode error - repeated field "floats" had too many elements') + } + + yield { + field: `${prefix}floats[]`, + index: obj.floats, + value: r.float() + } + + obj.floats++ + + break + } + case 3: { + if (opts.limits?.int32s != null && obj.int32s === opts.limits.int32s) { + throw new MaxLengthError('Streaming decode error - repeated field "int32s" had too many elements') + } + + yield { + field: `${prefix}int32s[]`, + index: obj.int32s, + value: r.int32() + } + + obj.int32s++ + + break + } + case 4: { + if (opts.limits?.int64s != null && obj.int64s === opts.limits.int64s) { + throw new MaxLengthError('Streaming decode error - repeated field "int64s" had too many elements') + } + + yield { + field: `${prefix}int64s[]`, + index: obj.int64s, + value: r.int64() + } + + obj.int64s++ + + break + } + case 5: { + if (opts.limits?.uint32s != null && obj.uint32s === opts.limits.uint32s) { + throw new MaxLengthError('Streaming decode error - repeated field "uint32s" had too many elements') + } + + yield { + field: `${prefix}uint32s[]`, + index: obj.uint32s, + value: r.uint32() + } + + obj.uint32s++ + + break + } + case 6: { + if (opts.limits?.uint64s != null && obj.uint64s === opts.limits.uint64s) { + throw new MaxLengthError('Streaming decode error - repeated field "uint64s" had too many elements') + } + + yield { + field: `${prefix}uint64s[]`, + index: obj.uint64s, + value: r.uint64() + } + + obj.uint64s++ + + break + } + case 7: { + if (opts.limits?.sint32s != null && obj.sint32s === opts.limits.sint32s) { + throw new MaxLengthError('Streaming decode error - repeated field "sint32s" had too many elements') + } + + yield { + field: `${prefix}sint32s[]`, + index: obj.sint32s, + value: r.sint32() + } + + obj.sint32s++ + + break + } + case 8: { + if (opts.limits?.sint64s != null && obj.sint64s === opts.limits.sint64s) { + throw new MaxLengthError('Streaming decode error - repeated field "sint64s" had too many elements') + } + + yield { + field: `${prefix}sint64s[]`, + index: obj.sint64s, + value: r.sint64() + } + + obj.sint64s++ + + break + } + case 9: { + if (opts.limits?.fixed32s != null && obj.fixed32s === opts.limits.fixed32s) { + throw new MaxLengthError('Streaming decode error - repeated field "fixed32s" had too many elements') + } + + yield { + field: `${prefix}fixed32s[]`, + index: obj.fixed32s, + value: r.fixed32() + } + + obj.fixed32s++ + + break + } + case 10: { + if (opts.limits?.fixed64s != null && obj.fixed64s === opts.limits.fixed64s) { + throw new MaxLengthError('Streaming decode error - repeated field "fixed64s" had too many elements') + } + + yield { + field: `${prefix}fixed64s[]`, + index: obj.fixed64s, + value: r.fixed64() + } + + obj.fixed64s++ + + break + } + case 11: { + if (opts.limits?.sfixed32s != null && obj.sfixed32s === opts.limits.sfixed32s) { + throw new MaxLengthError('Streaming decode error - repeated field "sfixed32s" had too many elements') + } + + yield { + field: `${prefix}sfixed32s[]`, + index: obj.sfixed32s, + value: r.sfixed32() + } + + obj.sfixed32s++ + + break + } + case 12: { + if (opts.limits?.sfixed64s != null && obj.sfixed64s === opts.limits.sfixed64s) { + throw new MaxLengthError('Streaming decode error - repeated field "sfixed64s" had too many elements') + } + + yield { + field: `${prefix}sfixed64s[]`, + index: obj.sfixed64s, + value: r.sfixed64() + } + + obj.sfixed64s++ + + break + } + case 13: { + if (opts.limits?.bools != null && obj.bools === opts.limits.bools) { + throw new MaxLengthError('Streaming decode error - repeated field "bools" had too many elements') + } + + yield { + field: `${prefix}bools[]`, + index: obj.bools, + value: r.bool() + } + + obj.bools++ + + break + } + default: { + r.skipType(tag & 7) + break + } + } + } + + if (prefix !== '.') { + yield { + field: prefix.endsWith('.') ? prefix.substring(0, prefix.length - 1) : prefix, + type: 'end', + message: 'Proto2DefaultPackedTypes' + } + } + }) + } + + return _codec + } + + export interface Proto2DefaultPackedTypesDoublesFieldEvent { + field: '.doubles[]' + index: number + value: number + } + + export interface Proto2DefaultPackedTypesFloatsFieldEvent { + field: '.floats[]' + index: number + value: number + } + + export interface Proto2DefaultPackedTypesInt32sFieldEvent { + field: '.int32s[]' + index: number + value: number + } + + export interface Proto2DefaultPackedTypesInt64sFieldEvent { + field: '.int64s[]' + index: number + value: bigint + } + + export interface Proto2DefaultPackedTypesUint32sFieldEvent { + field: '.uint32s[]' + index: number + value: number + } + + export interface Proto2DefaultPackedTypesUint64sFieldEvent { + field: '.uint64s[]' + index: number + value: bigint + } + + export interface Proto2DefaultPackedTypesSint32sFieldEvent { + field: '.sint32s[]' + index: number + value: number + } + + export interface Proto2DefaultPackedTypesSint64sFieldEvent { + field: '.sint64s[]' + index: number + value: bigint + } + + export interface Proto2DefaultPackedTypesFixed32sFieldEvent { + field: '.fixed32s[]' + index: number + value: number + } + + export interface Proto2DefaultPackedTypesFixed64sFieldEvent { + field: '.fixed64s[]' + index: number + value: bigint + } + + export interface Proto2DefaultPackedTypesSfixed32sFieldEvent { + field: '.sfixed32s[]' + index: number + value: number + } + + export interface Proto2DefaultPackedTypesSfixed64sFieldEvent { + field: '.sfixed64s[]' + index: number + value: bigint + } + + export interface Proto2DefaultPackedTypesBoolsFieldEvent { + field: '.bools[]' + index: number + value: boolean + } + + export function encode (obj: Proto2DefaultPackedTypesInput): Uint8Array { + return encodeMessage(obj, Proto2DefaultPackedTypes.codec()) + } + + export function decode (buf: Uint8Array | Uint8ArrayList, opts?: DecodeOptions): Proto2DefaultPackedTypes { + return decodeMessage(buf, Proto2DefaultPackedTypes.codec(), opts) + } + + export function stream (buf: Uint8Array | Uint8ArrayList, opts?: DecodeOptions): Generator { + return streamMessage(buf, Proto2DefaultPackedTypes.codec(), opts) + } +} + +export interface Proto2PackedTypes { + doubles: number[] + floats: number[] + int32s: number[] + int64s: bigint[] + uint32s: number[] + uint64s: bigint[] + sint32s: number[] + sint64s: bigint[] + fixed32s: number[] + fixed64s: bigint[] + sfixed32s: number[] + sfixed64s: bigint[] + bools: boolean[] +} + +export interface Proto2PackedTypesInput { + doubles?: number[] + floats?: number[] + int32s?: number[] + int64s?: bigint[] + uint32s?: number[] + uint64s?: bigint[] + sint32s?: number[] + sint64s?: bigint[] + fixed32s?: number[] + fixed64s?: bigint[] + sfixed32s?: number[] + sfixed64s?: bigint[] + bools?: boolean[] +} + +export namespace Proto2PackedTypes { + let _codec: Codec + + export const codec = (): Codec => { + if (_codec == null) { + _codec = message((obj, w, opts = {}) => { + if (opts.lengthDelimited !== false) { + w.fork() + } + + if (obj.doubles != null && obj.doubles.length > 0) { + w.uint32(10) + w.fork() + + for (const value of obj.doubles) { + w.double(value) + } + + w.ldelim() + } + + if (obj.floats != null && obj.floats.length > 0) { + w.uint32(18) + w.fork() + + for (const value of obj.floats) { + w.float(value) + } + + w.ldelim() + } + + if (obj.int32s != null && obj.int32s.length > 0) { + w.uint32(26) + w.fork() + + for (const value of obj.int32s) { + w.int32(value) + } + + w.ldelim() + } + + if (obj.int64s != null && obj.int64s.length > 0) { + w.uint32(34) + w.fork() + + for (const value of obj.int64s) { + w.int64(value) + } + + w.ldelim() + } + + if (obj.uint32s != null && obj.uint32s.length > 0) { + w.uint32(42) + w.fork() + + for (const value of obj.uint32s) { + w.uint32(value) + } + + w.ldelim() + } + + if (obj.uint64s != null && obj.uint64s.length > 0) { + w.uint32(50) + w.fork() + + for (const value of obj.uint64s) { + w.uint64(value) + } + + w.ldelim() + } + + if (obj.sint32s != null && obj.sint32s.length > 0) { + w.uint32(58) + w.fork() + + for (const value of obj.sint32s) { + w.sint32(value) + } + + w.ldelim() + } + + if (obj.sint64s != null && obj.sint64s.length > 0) { + w.uint32(66) + w.fork() + + for (const value of obj.sint64s) { + w.sint64(value) + } + + w.ldelim() + } + + if (obj.fixed32s != null && obj.fixed32s.length > 0) { + w.uint32(74) + w.fork() + + for (const value of obj.fixed32s) { + w.fixed32(value) + } + + w.ldelim() + } + + if (obj.fixed64s != null && obj.fixed64s.length > 0) { + w.uint32(82) + w.fork() + + for (const value of obj.fixed64s) { + w.fixed64(value) + } + + w.ldelim() + } + + if (obj.sfixed32s != null && obj.sfixed32s.length > 0) { + w.uint32(90) + w.fork() + + for (const value of obj.sfixed32s) { + w.sfixed32(value) + } + + w.ldelim() + } + + if (obj.sfixed64s != null && obj.sfixed64s.length > 0) { + w.uint32(98) + w.fork() + + for (const value of obj.sfixed64s) { + w.sfixed64(value) + } + + w.ldelim() + } + + if (obj.bools != null && obj.bools.length > 0) { + w.uint32(106) + w.fork() + + for (const value of obj.bools) { + w.bool(value) + } + + w.ldelim() + } + + if (opts.lengthDelimited !== false) { + w.ldelim() + } + }, (r, length, opts = {}) => { + const obj: any = { + doubles: [], + floats: [], + int32s: [], + int64s: [], + uint32s: [], + uint64s: [], + sint32s: [], + sint64s: [], + fixed32s: [], + fixed64s: [], + sfixed32s: [], + sfixed64s: [], + bools: [] + } + + const end = length == null ? r.len : r.pos + length + + while (r.pos < end) { + const tag = r.uint32() + + switch (tag >>> 3) { + case 1: { + const b = r.bytes() + const r2 = reader(b) + + while (r2.pos < r2.len) { + if (opts.limits?.doubles != null && obj.doubles.length === opts.limits.doubles) { + throw new MaxLengthError('Decode error - repeated field "doubles" had too many elements') + } + + obj.doubles.push(r2.double()) + } + + break + } + case 2: { + const b = r.bytes() + const r2 = reader(b) + + while (r2.pos < r2.len) { + if (opts.limits?.floats != null && obj.floats.length === opts.limits.floats) { + throw new MaxLengthError('Decode error - repeated field "floats" had too many elements') + } + + obj.floats.push(r2.float()) + } + + break + } + case 3: { + const b = r.bytes() + const r2 = reader(b) + + while (r2.pos < r2.len) { + if (opts.limits?.int32s != null && obj.int32s.length === opts.limits.int32s) { + throw new MaxLengthError('Decode error - repeated field "int32s" had too many elements') + } + + obj.int32s.push(r2.int32()) + } + + break + } + case 4: { + const b = r.bytes() + const r2 = reader(b) + + while (r2.pos < r2.len) { + if (opts.limits?.int64s != null && obj.int64s.length === opts.limits.int64s) { + throw new MaxLengthError('Decode error - repeated field "int64s" had too many elements') + } + + obj.int64s.push(r2.int64()) + } + + break + } + case 5: { + const b = r.bytes() + const r2 = reader(b) + + while (r2.pos < r2.len) { + if (opts.limits?.uint32s != null && obj.uint32s.length === opts.limits.uint32s) { + throw new MaxLengthError('Decode error - repeated field "uint32s" had too many elements') + } + + obj.uint32s.push(r2.uint32()) + } + + break + } + case 6: { + const b = r.bytes() + const r2 = reader(b) + + while (r2.pos < r2.len) { + if (opts.limits?.uint64s != null && obj.uint64s.length === opts.limits.uint64s) { + throw new MaxLengthError('Decode error - repeated field "uint64s" had too many elements') + } + + obj.uint64s.push(r2.uint64()) + } + + break + } + case 7: { + const b = r.bytes() + const r2 = reader(b) + + while (r2.pos < r2.len) { + if (opts.limits?.sint32s != null && obj.sint32s.length === opts.limits.sint32s) { + throw new MaxLengthError('Decode error - repeated field "sint32s" had too many elements') + } + + obj.sint32s.push(r2.sint32()) + } + + break + } + case 8: { + const b = r.bytes() + const r2 = reader(b) + + while (r2.pos < r2.len) { + if (opts.limits?.sint64s != null && obj.sint64s.length === opts.limits.sint64s) { + throw new MaxLengthError('Decode error - repeated field "sint64s" had too many elements') + } + + obj.sint64s.push(r2.sint64()) + } + + break + } + case 9: { + const b = r.bytes() + const r2 = reader(b) + + while (r2.pos < r2.len) { + if (opts.limits?.fixed32s != null && obj.fixed32s.length === opts.limits.fixed32s) { + throw new MaxLengthError('Decode error - repeated field "fixed32s" had too many elements') + } + + obj.fixed32s.push(r2.fixed32()) + } + + break + } + case 10: { + const b = r.bytes() + const r2 = reader(b) + + while (r2.pos < r2.len) { + if (opts.limits?.fixed64s != null && obj.fixed64s.length === opts.limits.fixed64s) { + throw new MaxLengthError('Decode error - repeated field "fixed64s" had too many elements') + } + + obj.fixed64s.push(r2.fixed64()) + } + + break + } + case 11: { + const b = r.bytes() + const r2 = reader(b) + + while (r2.pos < r2.len) { + if (opts.limits?.sfixed32s != null && obj.sfixed32s.length === opts.limits.sfixed32s) { + throw new MaxLengthError('Decode error - repeated field "sfixed32s" had too many elements') + } + + obj.sfixed32s.push(r2.sfixed32()) + } + + break + } + case 12: { + const b = r.bytes() + const r2 = reader(b) + + while (r2.pos < r2.len) { + if (opts.limits?.sfixed64s != null && obj.sfixed64s.length === opts.limits.sfixed64s) { + throw new MaxLengthError('Decode error - repeated field "sfixed64s" had too many elements') + } + + obj.sfixed64s.push(r2.sfixed64()) + } + + break + } + case 13: { + const b = r.bytes() + const r2 = reader(b) + + while (r2.pos < r2.len) { + if (opts.limits?.bools != null && obj.bools.length === opts.limits.bools) { + throw new MaxLengthError('Decode error - repeated field "bools" had too many elements') + } + + obj.bools.push(r2.bool()) + } + + break + } + default: { + r.skipType(tag & 7) + break + } + } + } + + return obj + }, function * (r, length, prefix, opts = {}) { + const obj = { + doubles: 0, + floats: 0, + int32s: 0, + int64s: 0, + uint32s: 0, + uint64s: 0, + sint32s: 0, + sint64s: 0, + fixed32s: 0, + fixed64s: 0, + sfixed32s: 0, + sfixed64s: 0, + bools: 0 + } + + const end = length == null ? r.len : r.pos + length + + if (prefix !== '.') { + yield { + field: prefix.endsWith('.') ? prefix.substring(0, prefix.length - 1) : prefix, + type: 'start', + message: 'Proto2PackedTypes' + } + } + + while (r.pos < end) { + const tag = r.uint32() + + switch (tag >>> 3) { + case 1: { + const b = r.bytes() + const r2 = reader(b) + + while (r2.pos < r2.len) { + if (opts.limits?.doubles != null && obj.doubles === opts.limits.doubles) { + throw new MaxLengthError('Streaming decode error - repeated field "doubles" had too many elements') + } + + yield { + field: `${prefix}doubles[]`, + index: obj.doubles, + value: r2.double() + } + + obj.doubles++ + } + + break + } + case 2: { + const b = r.bytes() + const r2 = reader(b) + + while (r2.pos < r2.len) { + if (opts.limits?.floats != null && obj.floats === opts.limits.floats) { + throw new MaxLengthError('Streaming decode error - repeated field "floats" had too many elements') + } + + yield { + field: `${prefix}floats[]`, + index: obj.floats, + value: r2.float() + } + + obj.floats++ + } + + break + } + case 3: { + const b = r.bytes() + const r2 = reader(b) + + while (r2.pos < r2.len) { + if (opts.limits?.int32s != null && obj.int32s === opts.limits.int32s) { + throw new MaxLengthError('Streaming decode error - repeated field "int32s" had too many elements') + } + + yield { + field: `${prefix}int32s[]`, + index: obj.int32s, + value: r2.int32() + } + + obj.int32s++ + } + + break + } + case 4: { + const b = r.bytes() + const r2 = reader(b) + + while (r2.pos < r2.len) { + if (opts.limits?.int64s != null && obj.int64s === opts.limits.int64s) { + throw new MaxLengthError('Streaming decode error - repeated field "int64s" had too many elements') + } + + yield { + field: `${prefix}int64s[]`, + index: obj.int64s, + value: r2.int64() + } + + obj.int64s++ + } + + break + } + case 5: { + const b = r.bytes() + const r2 = reader(b) + + while (r2.pos < r2.len) { + if (opts.limits?.uint32s != null && obj.uint32s === opts.limits.uint32s) { + throw new MaxLengthError('Streaming decode error - repeated field "uint32s" had too many elements') + } + + yield { + field: `${prefix}uint32s[]`, + index: obj.uint32s, + value: r2.uint32() + } + + obj.uint32s++ + } + + break + } + case 6: { + const b = r.bytes() + const r2 = reader(b) + + while (r2.pos < r2.len) { + if (opts.limits?.uint64s != null && obj.uint64s === opts.limits.uint64s) { + throw new MaxLengthError('Streaming decode error - repeated field "uint64s" had too many elements') + } + + yield { + field: `${prefix}uint64s[]`, + index: obj.uint64s, + value: r2.uint64() + } + + obj.uint64s++ + } + + break + } + case 7: { + const b = r.bytes() + const r2 = reader(b) + + while (r2.pos < r2.len) { + if (opts.limits?.sint32s != null && obj.sint32s === opts.limits.sint32s) { + throw new MaxLengthError('Streaming decode error - repeated field "sint32s" had too many elements') + } + + yield { + field: `${prefix}sint32s[]`, + index: obj.sint32s, + value: r2.sint32() + } + + obj.sint32s++ + } + + break + } + case 8: { + const b = r.bytes() + const r2 = reader(b) + + while (r2.pos < r2.len) { + if (opts.limits?.sint64s != null && obj.sint64s === opts.limits.sint64s) { + throw new MaxLengthError('Streaming decode error - repeated field "sint64s" had too many elements') + } + + yield { + field: `${prefix}sint64s[]`, + index: obj.sint64s, + value: r2.sint64() + } + + obj.sint64s++ + } + + break + } + case 9: { + const b = r.bytes() + const r2 = reader(b) + + while (r2.pos < r2.len) { + if (opts.limits?.fixed32s != null && obj.fixed32s === opts.limits.fixed32s) { + throw new MaxLengthError('Streaming decode error - repeated field "fixed32s" had too many elements') + } + + yield { + field: `${prefix}fixed32s[]`, + index: obj.fixed32s, + value: r2.fixed32() + } + + obj.fixed32s++ + } + + break + } + case 10: { + const b = r.bytes() + const r2 = reader(b) + + while (r2.pos < r2.len) { + if (opts.limits?.fixed64s != null && obj.fixed64s === opts.limits.fixed64s) { + throw new MaxLengthError('Streaming decode error - repeated field "fixed64s" had too many elements') + } + + yield { + field: `${prefix}fixed64s[]`, + index: obj.fixed64s, + value: r2.fixed64() + } + + obj.fixed64s++ + } + + break + } + case 11: { + const b = r.bytes() + const r2 = reader(b) + + while (r2.pos < r2.len) { + if (opts.limits?.sfixed32s != null && obj.sfixed32s === opts.limits.sfixed32s) { + throw new MaxLengthError('Streaming decode error - repeated field "sfixed32s" had too many elements') + } + + yield { + field: `${prefix}sfixed32s[]`, + index: obj.sfixed32s, + value: r2.sfixed32() + } + + obj.sfixed32s++ + } + + break + } + case 12: { + const b = r.bytes() + const r2 = reader(b) + + while (r2.pos < r2.len) { + if (opts.limits?.sfixed64s != null && obj.sfixed64s === opts.limits.sfixed64s) { + throw new MaxLengthError('Streaming decode error - repeated field "sfixed64s" had too many elements') + } + + yield { + field: `${prefix}sfixed64s[]`, + index: obj.sfixed64s, + value: r2.sfixed64() + } + + obj.sfixed64s++ + } + + break + } + case 13: { + const b = r.bytes() + const r2 = reader(b) + + while (r2.pos < r2.len) { + if (opts.limits?.bools != null && obj.bools === opts.limits.bools) { + throw new MaxLengthError('Streaming decode error - repeated field "bools" had too many elements') + } + + yield { + field: `${prefix}bools[]`, + index: obj.bools, + value: r2.bool() + } + + obj.bools++ + } + + break + } + default: { + r.skipType(tag & 7) + break + } + } + } + + if (prefix !== '.') { + yield { + field: prefix.endsWith('.') ? prefix.substring(0, prefix.length - 1) : prefix, + type: 'end', + message: 'Proto2PackedTypes' + } + } + }) + } + + return _codec + } + + export interface Proto2PackedTypesDoublesFieldEvent { + field: '.doubles[]' + index: number + value: number + } + + export interface Proto2PackedTypesFloatsFieldEvent { + field: '.floats[]' + index: number + value: number + } + + export interface Proto2PackedTypesInt32sFieldEvent { + field: '.int32s[]' + index: number + value: number + } + + export interface Proto2PackedTypesInt64sFieldEvent { + field: '.int64s[]' + index: number + value: bigint + } + + export interface Proto2PackedTypesUint32sFieldEvent { + field: '.uint32s[]' + index: number + value: number + } + + export interface Proto2PackedTypesUint64sFieldEvent { + field: '.uint64s[]' + index: number + value: bigint + } + + export interface Proto2PackedTypesSint32sFieldEvent { + field: '.sint32s[]' + index: number + value: number + } + + export interface Proto2PackedTypesSint64sFieldEvent { + field: '.sint64s[]' + index: number + value: bigint + } + + export interface Proto2PackedTypesFixed32sFieldEvent { + field: '.fixed32s[]' + index: number + value: number + } + + export interface Proto2PackedTypesFixed64sFieldEvent { + field: '.fixed64s[]' + index: number + value: bigint + } + + export interface Proto2PackedTypesSfixed32sFieldEvent { + field: '.sfixed32s[]' + index: number + value: number + } + + export interface Proto2PackedTypesSfixed64sFieldEvent { + field: '.sfixed64s[]' + index: number + value: bigint + } + + export interface Proto2PackedTypesBoolsFieldEvent { + field: '.bools[]' + index: number + value: boolean + } + + export function encode (obj: Proto2PackedTypesInput): Uint8Array { + return encodeMessage(obj, Proto2PackedTypes.codec()) + } + + export function decode (buf: Uint8Array | Uint8ArrayList, opts?: DecodeOptions): Proto2PackedTypes { + return decodeMessage(buf, Proto2PackedTypes.codec(), opts) + } + + export function stream (buf: Uint8Array | Uint8ArrayList, opts?: DecodeOptions): Generator { + return streamMessage(buf, Proto2PackedTypes.codec(), opts) + } +} + +export interface Proto2ExpandedTypes { + doubles: number[] + floats: number[] + int32s: number[] + int64s: bigint[] + uint32s: number[] + uint64s: bigint[] + sint32s: number[] + sint64s: bigint[] + fixed32s: number[] + fixed64s: bigint[] + sfixed32s: number[] + sfixed64s: bigint[] + bools: boolean[] +} + +export interface Proto2ExpandedTypesInput { + doubles?: number[] + floats?: number[] + int32s?: number[] + int64s?: bigint[] + uint32s?: number[] + uint64s?: bigint[] + sint32s?: number[] + sint64s?: bigint[] + fixed32s?: number[] + fixed64s?: bigint[] + sfixed32s?: number[] + sfixed64s?: bigint[] + bools?: boolean[] +} + +export namespace Proto2ExpandedTypes { + let _codec: Codec + + export const codec = (): Codec => { + if (_codec == null) { + _codec = message((obj, w, opts = {}) => { + if (opts.lengthDelimited !== false) { + w.fork() + } + + if (obj.doubles != null && obj.doubles.length > 0) { + for (const value of obj.doubles) { + w.uint32(9) + w.double(value) + } + } + + if (obj.floats != null && obj.floats.length > 0) { + for (const value of obj.floats) { + w.uint32(21) + w.float(value) + } + } + + if (obj.int32s != null && obj.int32s.length > 0) { + for (const value of obj.int32s) { + w.uint32(24) + w.int32(value) + } + } + + if (obj.int64s != null && obj.int64s.length > 0) { + for (const value of obj.int64s) { + w.uint32(32) + w.int64(value) + } + } + + if (obj.uint32s != null && obj.uint32s.length > 0) { + for (const value of obj.uint32s) { + w.uint32(40) + w.uint32(value) + } + } + + if (obj.uint64s != null && obj.uint64s.length > 0) { + for (const value of obj.uint64s) { + w.uint32(48) + w.uint64(value) + } + } + + if (obj.sint32s != null && obj.sint32s.length > 0) { + for (const value of obj.sint32s) { + w.uint32(56) + w.sint32(value) + } + } + + if (obj.sint64s != null && obj.sint64s.length > 0) { + for (const value of obj.sint64s) { + w.uint32(64) + w.sint64(value) + } + } + + if (obj.fixed32s != null && obj.fixed32s.length > 0) { + for (const value of obj.fixed32s) { + w.uint32(77) + w.fixed32(value) + } + } + + if (obj.fixed64s != null && obj.fixed64s.length > 0) { + for (const value of obj.fixed64s) { + w.uint32(81) + w.fixed64(value) + } + } + + if (obj.sfixed32s != null && obj.sfixed32s.length > 0) { + for (const value of obj.sfixed32s) { + w.uint32(93) + w.sfixed32(value) + } + } + + if (obj.sfixed64s != null && obj.sfixed64s.length > 0) { + for (const value of obj.sfixed64s) { + w.uint32(97) + w.sfixed64(value) + } + } + + if (obj.bools != null && obj.bools.length > 0) { + for (const value of obj.bools) { + w.uint32(104) + w.bool(value) + } + } + + if (opts.lengthDelimited !== false) { + w.ldelim() + } + }, (r, length, opts = {}) => { + const obj: any = { + doubles: [], + floats: [], + int32s: [], + int64s: [], + uint32s: [], + uint64s: [], + sint32s: [], + sint64s: [], + fixed32s: [], + fixed64s: [], + sfixed32s: [], + sfixed64s: [], + bools: [] + } + + const end = length == null ? r.len : r.pos + length + + while (r.pos < end) { + const tag = r.uint32() + + switch (tag >>> 3) { + case 1: { + if (opts.limits?.doubles != null && obj.doubles.length === opts.limits.doubles) { + throw new MaxLengthError('Decode error - repeated field "doubles" had too many elements') + } + + obj.doubles.push(r.double()) + break + } + case 2: { + if (opts.limits?.floats != null && obj.floats.length === opts.limits.floats) { + throw new MaxLengthError('Decode error - repeated field "floats" had too many elements') + } + + obj.floats.push(r.float()) + break + } + case 3: { + if (opts.limits?.int32s != null && obj.int32s.length === opts.limits.int32s) { + throw new MaxLengthError('Decode error - repeated field "int32s" had too many elements') + } + + obj.int32s.push(r.int32()) + break + } + case 4: { + if (opts.limits?.int64s != null && obj.int64s.length === opts.limits.int64s) { + throw new MaxLengthError('Decode error - repeated field "int64s" had too many elements') + } + + obj.int64s.push(r.int64()) + break + } + case 5: { + if (opts.limits?.uint32s != null && obj.uint32s.length === opts.limits.uint32s) { + throw new MaxLengthError('Decode error - repeated field "uint32s" had too many elements') + } + + obj.uint32s.push(r.uint32()) + break + } + case 6: { + if (opts.limits?.uint64s != null && obj.uint64s.length === opts.limits.uint64s) { + throw new MaxLengthError('Decode error - repeated field "uint64s" had too many elements') + } + + obj.uint64s.push(r.uint64()) + break + } + case 7: { + if (opts.limits?.sint32s != null && obj.sint32s.length === opts.limits.sint32s) { + throw new MaxLengthError('Decode error - repeated field "sint32s" had too many elements') + } + + obj.sint32s.push(r.sint32()) + break + } + case 8: { + if (opts.limits?.sint64s != null && obj.sint64s.length === opts.limits.sint64s) { + throw new MaxLengthError('Decode error - repeated field "sint64s" had too many elements') + } + + obj.sint64s.push(r.sint64()) + break + } + case 9: { + if (opts.limits?.fixed32s != null && obj.fixed32s.length === opts.limits.fixed32s) { + throw new MaxLengthError('Decode error - repeated field "fixed32s" had too many elements') + } + + obj.fixed32s.push(r.fixed32()) + break + } + case 10: { + if (opts.limits?.fixed64s != null && obj.fixed64s.length === opts.limits.fixed64s) { + throw new MaxLengthError('Decode error - repeated field "fixed64s" had too many elements') + } + + obj.fixed64s.push(r.fixed64()) + break + } + case 11: { + if (opts.limits?.sfixed32s != null && obj.sfixed32s.length === opts.limits.sfixed32s) { + throw new MaxLengthError('Decode error - repeated field "sfixed32s" had too many elements') + } + + obj.sfixed32s.push(r.sfixed32()) + break + } + case 12: { + if (opts.limits?.sfixed64s != null && obj.sfixed64s.length === opts.limits.sfixed64s) { + throw new MaxLengthError('Decode error - repeated field "sfixed64s" had too many elements') + } + + obj.sfixed64s.push(r.sfixed64()) + break + } + case 13: { + if (opts.limits?.bools != null && obj.bools.length === opts.limits.bools) { + throw new MaxLengthError('Decode error - repeated field "bools" had too many elements') + } + + obj.bools.push(r.bool()) + break + } + default: { + r.skipType(tag & 7) + break + } + } + } + + return obj + }, function * (r, length, prefix, opts = {}) { + const obj = { + doubles: 0, + floats: 0, + int32s: 0, + int64s: 0, + uint32s: 0, + uint64s: 0, + sint32s: 0, + sint64s: 0, + fixed32s: 0, + fixed64s: 0, + sfixed32s: 0, + sfixed64s: 0, + bools: 0 + } + + const end = length == null ? r.len : r.pos + length + + if (prefix !== '.') { + yield { + field: prefix.endsWith('.') ? prefix.substring(0, prefix.length - 1) : prefix, + type: 'start', + message: 'Proto2ExpandedTypes' + } + } + + while (r.pos < end) { + const tag = r.uint32() + + switch (tag >>> 3) { + case 1: { + if (opts.limits?.doubles != null && obj.doubles === opts.limits.doubles) { + throw new MaxLengthError('Streaming decode error - repeated field "doubles" had too many elements') + } + + yield { + field: `${prefix}doubles[]`, + index: obj.doubles, + value: r.double() + } + + obj.doubles++ + + break + } + case 2: { + if (opts.limits?.floats != null && obj.floats === opts.limits.floats) { + throw new MaxLengthError('Streaming decode error - repeated field "floats" had too many elements') + } + + yield { + field: `${prefix}floats[]`, + index: obj.floats, + value: r.float() + } + + obj.floats++ + + break + } + case 3: { + if (opts.limits?.int32s != null && obj.int32s === opts.limits.int32s) { + throw new MaxLengthError('Streaming decode error - repeated field "int32s" had too many elements') + } + + yield { + field: `${prefix}int32s[]`, + index: obj.int32s, + value: r.int32() + } + + obj.int32s++ + + break + } + case 4: { + if (opts.limits?.int64s != null && obj.int64s === opts.limits.int64s) { + throw new MaxLengthError('Streaming decode error - repeated field "int64s" had too many elements') + } + + yield { + field: `${prefix}int64s[]`, + index: obj.int64s, + value: r.int64() + } + + obj.int64s++ + + break + } + case 5: { + if (opts.limits?.uint32s != null && obj.uint32s === opts.limits.uint32s) { + throw new MaxLengthError('Streaming decode error - repeated field "uint32s" had too many elements') + } + + yield { + field: `${prefix}uint32s[]`, + index: obj.uint32s, + value: r.uint32() + } + + obj.uint32s++ + + break + } + case 6: { + if (opts.limits?.uint64s != null && obj.uint64s === opts.limits.uint64s) { + throw new MaxLengthError('Streaming decode error - repeated field "uint64s" had too many elements') + } + + yield { + field: `${prefix}uint64s[]`, + index: obj.uint64s, + value: r.uint64() + } + + obj.uint64s++ + + break + } + case 7: { + if (opts.limits?.sint32s != null && obj.sint32s === opts.limits.sint32s) { + throw new MaxLengthError('Streaming decode error - repeated field "sint32s" had too many elements') + } + + yield { + field: `${prefix}sint32s[]`, + index: obj.sint32s, + value: r.sint32() + } + + obj.sint32s++ + + break + } + case 8: { + if (opts.limits?.sint64s != null && obj.sint64s === opts.limits.sint64s) { + throw new MaxLengthError('Streaming decode error - repeated field "sint64s" had too many elements') + } + + yield { + field: `${prefix}sint64s[]`, + index: obj.sint64s, + value: r.sint64() + } + + obj.sint64s++ + + break + } + case 9: { + if (opts.limits?.fixed32s != null && obj.fixed32s === opts.limits.fixed32s) { + throw new MaxLengthError('Streaming decode error - repeated field "fixed32s" had too many elements') + } + + yield { + field: `${prefix}fixed32s[]`, + index: obj.fixed32s, + value: r.fixed32() + } + + obj.fixed32s++ + + break + } + case 10: { + if (opts.limits?.fixed64s != null && obj.fixed64s === opts.limits.fixed64s) { + throw new MaxLengthError('Streaming decode error - repeated field "fixed64s" had too many elements') + } + + yield { + field: `${prefix}fixed64s[]`, + index: obj.fixed64s, + value: r.fixed64() + } + + obj.fixed64s++ + + break + } + case 11: { + if (opts.limits?.sfixed32s != null && obj.sfixed32s === opts.limits.sfixed32s) { + throw new MaxLengthError('Streaming decode error - repeated field "sfixed32s" had too many elements') + } + + yield { + field: `${prefix}sfixed32s[]`, + index: obj.sfixed32s, + value: r.sfixed32() + } + + obj.sfixed32s++ + + break + } + case 12: { + if (opts.limits?.sfixed64s != null && obj.sfixed64s === opts.limits.sfixed64s) { + throw new MaxLengthError('Streaming decode error - repeated field "sfixed64s" had too many elements') + } + + yield { + field: `${prefix}sfixed64s[]`, + index: obj.sfixed64s, + value: r.sfixed64() + } + + obj.sfixed64s++ + + break + } + case 13: { + if (opts.limits?.bools != null && obj.bools === opts.limits.bools) { + throw new MaxLengthError('Streaming decode error - repeated field "bools" had too many elements') + } + + yield { + field: `${prefix}bools[]`, + index: obj.bools, + value: r.bool() + } + + obj.bools++ + + break + } + default: { + r.skipType(tag & 7) + break + } + } + } + + if (prefix !== '.') { + yield { + field: prefix.endsWith('.') ? prefix.substring(0, prefix.length - 1) : prefix, + type: 'end', + message: 'Proto2ExpandedTypes' + } + } + }) + } + + return _codec + } + + export interface Proto2ExpandedTypesDoublesFieldEvent { + field: '.doubles[]' + index: number + value: number + } + + export interface Proto2ExpandedTypesFloatsFieldEvent { + field: '.floats[]' + index: number + value: number + } + + export interface Proto2ExpandedTypesInt32sFieldEvent { + field: '.int32s[]' + index: number + value: number + } + + export interface Proto2ExpandedTypesInt64sFieldEvent { + field: '.int64s[]' + index: number + value: bigint + } + + export interface Proto2ExpandedTypesUint32sFieldEvent { + field: '.uint32s[]' + index: number + value: number + } + + export interface Proto2ExpandedTypesUint64sFieldEvent { + field: '.uint64s[]' + index: number + value: bigint + } + + export interface Proto2ExpandedTypesSint32sFieldEvent { + field: '.sint32s[]' + index: number + value: number + } + + export interface Proto2ExpandedTypesSint64sFieldEvent { + field: '.sint64s[]' + index: number + value: bigint + } + + export interface Proto2ExpandedTypesFixed32sFieldEvent { + field: '.fixed32s[]' + index: number + value: number + } + + export interface Proto2ExpandedTypesFixed64sFieldEvent { + field: '.fixed64s[]' + index: number + value: bigint + } + + export interface Proto2ExpandedTypesSfixed32sFieldEvent { + field: '.sfixed32s[]' + index: number + value: number + } + + export interface Proto2ExpandedTypesSfixed64sFieldEvent { + field: '.sfixed64s[]' + index: number + value: bigint + } + + export interface Proto2ExpandedTypesBoolsFieldEvent { + field: '.bools[]' + index: number + value: boolean + } + + export function encode (obj: Proto2ExpandedTypesInput): Uint8Array { + return encodeMessage(obj, Proto2ExpandedTypes.codec()) + } + + export function decode (buf: Uint8Array | Uint8ArrayList, opts?: DecodeOptions): Proto2ExpandedTypes { + return decodeMessage(buf, Proto2ExpandedTypes.codec(), opts) + } + + export function stream (buf: Uint8Array | Uint8ArrayList, opts?: DecodeOptions): Generator { + return streamMessage(buf, Proto2ExpandedTypes.codec(), opts) + } +} diff --git a/packages/protons/test/fixtures/packed.proto b/packages/protons/test/fixtures/packed.proto index ba434b6..44ad7b2 100644 --- a/packages/protons/test/fixtures/packed.proto +++ b/packages/protons/test/fixtures/packed.proto @@ -21,39 +21,7 @@ message DefaultPackedTypes { repeated bool bools = 13; } -message PackedTypes { - repeated double doubles = 1 [packed=true]; - repeated float floats = 2 [packed=true]; - repeated int32 int32s = 3 [packed=true]; - repeated int64 int64s = 4 [packed=true]; - repeated uint32 uint32s = 5 [packed=true]; - repeated uint64 uint64s = 6 [packed=true]; - repeated sint32 sint32s = 7 [packed=true]; - repeated sint64 sint64s = 8 [packed=true]; - repeated fixed32 fixed32s = 9 [packed=true]; - repeated fixed64 fixed64s = 10 [packed=true]; - repeated sfixed32 sfixed32s = 11 [packed=true]; - repeated sfixed64 sfixed64s = 12 [packed=true]; - repeated bool bools = 13 [packed=true]; -} - -message ExpandedTypes { - repeated double doubles = 1 [packed=false]; - repeated float floats = 2 [packed=false]; - repeated int32 int32s = 3 [packed=false]; - repeated int64 int64s = 4 [packed=false]; - repeated uint32 uint32s = 5 [packed=false]; - repeated uint64 uint64s = 6 [packed=false]; - repeated sint32 sint32s = 7 [packed=false]; - repeated sint64 sint64s = 8 [packed=false]; - repeated fixed32 fixed32s = 9 [packed=false]; - repeated fixed64 fixed64s = 10 [packed=false]; - repeated sfixed32 sfixed32s = 11 [packed=false]; - repeated sfixed64 sfixed64s = 12 [packed=false]; - repeated bool bools = 13 [packed=false]; -} - -message NewOptionPackedTypes { +message OptionPackedTypes { repeated double doubles = 1 [features.repeated_field_encoding=PACKED]; repeated float floats = 2 [features.repeated_field_encoding=PACKED]; repeated int32 int32s = 3 [features.repeated_field_encoding=PACKED]; @@ -69,7 +37,7 @@ message NewOptionPackedTypes { repeated bool bools = 13 [features.repeated_field_encoding=PACKED]; } -message NewOptionExpandedTypes { +message OptionExpandedTypes { repeated double doubles = 1 [features.repeated_field_encoding=EXPANDED]; repeated float floats = 2 [features.repeated_field_encoding=EXPANDED]; repeated int32 int32s = 3 [features.repeated_field_encoding=EXPANDED]; diff --git a/packages/protons/test/fixtures/packed.ts b/packages/protons/test/fixtures/packed.ts index 584cf60..b54006c 100644 --- a/packages/protons/test/fixtures/packed.ts +++ b/packages/protons/test/fixtures/packed.ts @@ -972,7 +972,7 @@ export namespace DefaultPackedTypes { } } -export interface PackedTypes { +export interface OptionPackedTypes { doubles: number[] floats: number[] int32s: number[] @@ -988,7 +988,7 @@ export interface PackedTypes { bools: boolean[] } -export interface PackedTypesInput { +export interface OptionPackedTypesInput { doubles?: number[] floats?: number[] int32s?: number[] @@ -1004,12 +1004,12 @@ export interface PackedTypesInput { bools?: boolean[] } -export namespace PackedTypes { - let _codec: Codec +export namespace OptionPackedTypes { + let _codec: Codec - export const codec = (): Codec => { + export const codec = (): Codec => { if (_codec == null) { - _codec = message((obj, w, opts = {}) => { + _codec = message((obj, w, opts = {}) => { if (opts.lengthDelimited !== false) { w.fork() } @@ -1396,7 +1396,7 @@ export namespace PackedTypes { yield { field: prefix.endsWith('.') ? prefix.substring(0, prefix.length - 1) : prefix, type: 'start', - message: 'PackedTypes' + message: 'OptionPackedTypes' } } @@ -1675,7 +1675,7 @@ export namespace PackedTypes { yield { field: prefix.endsWith('.') ? prefix.substring(0, prefix.length - 1) : prefix, type: 'end', - message: 'PackedTypes' + message: 'OptionPackedTypes' } } }) @@ -1684,98 +1684,98 @@ export namespace PackedTypes { return _codec } - export interface PackedTypesDoublesFieldEvent { + export interface OptionPackedTypesDoublesFieldEvent { field: '.doubles[]' index: number value: number } - export interface PackedTypesFloatsFieldEvent { + export interface OptionPackedTypesFloatsFieldEvent { field: '.floats[]' index: number value: number } - export interface PackedTypesInt32sFieldEvent { + export interface OptionPackedTypesInt32sFieldEvent { field: '.int32s[]' index: number value: number } - export interface PackedTypesInt64sFieldEvent { + export interface OptionPackedTypesInt64sFieldEvent { field: '.int64s[]' index: number value: bigint } - export interface PackedTypesUint32sFieldEvent { + export interface OptionPackedTypesUint32sFieldEvent { field: '.uint32s[]' index: number value: number } - export interface PackedTypesUint64sFieldEvent { + export interface OptionPackedTypesUint64sFieldEvent { field: '.uint64s[]' index: number value: bigint } - export interface PackedTypesSint32sFieldEvent { + export interface OptionPackedTypesSint32sFieldEvent { field: '.sint32s[]' index: number value: number } - export interface PackedTypesSint64sFieldEvent { + export interface OptionPackedTypesSint64sFieldEvent { field: '.sint64s[]' index: number value: bigint } - export interface PackedTypesFixed32sFieldEvent { + export interface OptionPackedTypesFixed32sFieldEvent { field: '.fixed32s[]' index: number value: number } - export interface PackedTypesFixed64sFieldEvent { + export interface OptionPackedTypesFixed64sFieldEvent { field: '.fixed64s[]' index: number value: bigint } - export interface PackedTypesSfixed32sFieldEvent { + export interface OptionPackedTypesSfixed32sFieldEvent { field: '.sfixed32s[]' index: number value: number } - export interface PackedTypesSfixed64sFieldEvent { + export interface OptionPackedTypesSfixed64sFieldEvent { field: '.sfixed64s[]' index: number value: bigint } - export interface PackedTypesBoolsFieldEvent { + export interface OptionPackedTypesBoolsFieldEvent { field: '.bools[]' index: number value: boolean } - export function encode (obj: PackedTypesInput): Uint8Array { - return encodeMessage(obj, PackedTypes.codec()) + export function encode (obj: OptionPackedTypesInput): Uint8Array { + return encodeMessage(obj, OptionPackedTypes.codec()) } - export function decode (buf: Uint8Array | Uint8ArrayList, opts?: DecodeOptions): PackedTypes { - return decodeMessage(buf, PackedTypes.codec(), opts) + export function decode (buf: Uint8Array | Uint8ArrayList, opts?: DecodeOptions): OptionPackedTypes { + return decodeMessage(buf, OptionPackedTypes.codec(), opts) } - export function stream (buf: Uint8Array | Uint8ArrayList, opts?: DecodeOptions): Generator { - return streamMessage(buf, PackedTypes.codec(), opts) + export function stream (buf: Uint8Array | Uint8ArrayList, opts?: DecodeOptions): Generator { + return streamMessage(buf, OptionPackedTypes.codec(), opts) } } -export interface ExpandedTypes { +export interface OptionExpandedTypes { doubles: number[] floats: number[] int32s: number[] @@ -1791,7 +1791,7 @@ export interface ExpandedTypes { bools: boolean[] } -export interface ExpandedTypesInput { +export interface OptionExpandedTypesInput { doubles?: number[] floats?: number[] int32s?: number[] @@ -1807,1618 +1807,12 @@ export interface ExpandedTypesInput { bools?: boolean[] } -export namespace ExpandedTypes { - let _codec: Codec +export namespace OptionExpandedTypes { + let _codec: Codec - export const codec = (): Codec => { + export const codec = (): Codec => { if (_codec == null) { - _codec = message((obj, w, opts = {}) => { - if (opts.lengthDelimited !== false) { - w.fork() - } - - if (obj.doubles != null && obj.doubles.length > 0) { - w.uint32(10) - w.fork() - - for (const value of obj.doubles) { - w.double(value) - } - - w.ldelim() - } - - if (obj.floats != null && obj.floats.length > 0) { - w.uint32(18) - w.fork() - - for (const value of obj.floats) { - w.float(value) - } - - w.ldelim() - } - - if (obj.int32s != null && obj.int32s.length > 0) { - w.uint32(26) - w.fork() - - for (const value of obj.int32s) { - w.int32(value) - } - - w.ldelim() - } - - if (obj.int64s != null && obj.int64s.length > 0) { - w.uint32(34) - w.fork() - - for (const value of obj.int64s) { - w.int64(value) - } - - w.ldelim() - } - - if (obj.uint32s != null && obj.uint32s.length > 0) { - w.uint32(42) - w.fork() - - for (const value of obj.uint32s) { - w.uint32(value) - } - - w.ldelim() - } - - if (obj.uint64s != null && obj.uint64s.length > 0) { - w.uint32(50) - w.fork() - - for (const value of obj.uint64s) { - w.uint64(value) - } - - w.ldelim() - } - - if (obj.sint32s != null && obj.sint32s.length > 0) { - w.uint32(58) - w.fork() - - for (const value of obj.sint32s) { - w.sint32(value) - } - - w.ldelim() - } - - if (obj.sint64s != null && obj.sint64s.length > 0) { - w.uint32(66) - w.fork() - - for (const value of obj.sint64s) { - w.sint64(value) - } - - w.ldelim() - } - - if (obj.fixed32s != null && obj.fixed32s.length > 0) { - w.uint32(74) - w.fork() - - for (const value of obj.fixed32s) { - w.fixed32(value) - } - - w.ldelim() - } - - if (obj.fixed64s != null && obj.fixed64s.length > 0) { - w.uint32(82) - w.fork() - - for (const value of obj.fixed64s) { - w.fixed64(value) - } - - w.ldelim() - } - - if (obj.sfixed32s != null && obj.sfixed32s.length > 0) { - w.uint32(90) - w.fork() - - for (const value of obj.sfixed32s) { - w.sfixed32(value) - } - - w.ldelim() - } - - if (obj.sfixed64s != null && obj.sfixed64s.length > 0) { - w.uint32(98) - w.fork() - - for (const value of obj.sfixed64s) { - w.sfixed64(value) - } - - w.ldelim() - } - - if (obj.bools != null && obj.bools.length > 0) { - w.uint32(106) - w.fork() - - for (const value of obj.bools) { - w.bool(value) - } - - w.ldelim() - } - - if (opts.lengthDelimited !== false) { - w.ldelim() - } - }, (r, length, opts = {}) => { - const obj: any = { - doubles: [], - floats: [], - int32s: [], - int64s: [], - uint32s: [], - uint64s: [], - sint32s: [], - sint64s: [], - fixed32s: [], - fixed64s: [], - sfixed32s: [], - sfixed64s: [], - bools: [] - } - - const end = length == null ? r.len : r.pos + length - - while (r.pos < end) { - const tag = r.uint32() - - switch (tag >>> 3) { - case 1: { - const b = r.bytes() - const r2 = reader(b) - - while (r2.pos < r2.len) { - if (opts.limits?.doubles != null && obj.doubles.length === opts.limits.doubles) { - throw new MaxLengthError('Decode error - repeated field "doubles" had too many elements') - } - - obj.doubles.push(r2.double()) - } - - break - } - case 2: { - const b = r.bytes() - const r2 = reader(b) - - while (r2.pos < r2.len) { - if (opts.limits?.floats != null && obj.floats.length === opts.limits.floats) { - throw new MaxLengthError('Decode error - repeated field "floats" had too many elements') - } - - obj.floats.push(r2.float()) - } - - break - } - case 3: { - const b = r.bytes() - const r2 = reader(b) - - while (r2.pos < r2.len) { - if (opts.limits?.int32s != null && obj.int32s.length === opts.limits.int32s) { - throw new MaxLengthError('Decode error - repeated field "int32s" had too many elements') - } - - obj.int32s.push(r2.int32()) - } - - break - } - case 4: { - const b = r.bytes() - const r2 = reader(b) - - while (r2.pos < r2.len) { - if (opts.limits?.int64s != null && obj.int64s.length === opts.limits.int64s) { - throw new MaxLengthError('Decode error - repeated field "int64s" had too many elements') - } - - obj.int64s.push(r2.int64()) - } - - break - } - case 5: { - const b = r.bytes() - const r2 = reader(b) - - while (r2.pos < r2.len) { - if (opts.limits?.uint32s != null && obj.uint32s.length === opts.limits.uint32s) { - throw new MaxLengthError('Decode error - repeated field "uint32s" had too many elements') - } - - obj.uint32s.push(r2.uint32()) - } - - break - } - case 6: { - const b = r.bytes() - const r2 = reader(b) - - while (r2.pos < r2.len) { - if (opts.limits?.uint64s != null && obj.uint64s.length === opts.limits.uint64s) { - throw new MaxLengthError('Decode error - repeated field "uint64s" had too many elements') - } - - obj.uint64s.push(r2.uint64()) - } - - break - } - case 7: { - const b = r.bytes() - const r2 = reader(b) - - while (r2.pos < r2.len) { - if (opts.limits?.sint32s != null && obj.sint32s.length === opts.limits.sint32s) { - throw new MaxLengthError('Decode error - repeated field "sint32s" had too many elements') - } - - obj.sint32s.push(r2.sint32()) - } - - break - } - case 8: { - const b = r.bytes() - const r2 = reader(b) - - while (r2.pos < r2.len) { - if (opts.limits?.sint64s != null && obj.sint64s.length === opts.limits.sint64s) { - throw new MaxLengthError('Decode error - repeated field "sint64s" had too many elements') - } - - obj.sint64s.push(r2.sint64()) - } - - break - } - case 9: { - const b = r.bytes() - const r2 = reader(b) - - while (r2.pos < r2.len) { - if (opts.limits?.fixed32s != null && obj.fixed32s.length === opts.limits.fixed32s) { - throw new MaxLengthError('Decode error - repeated field "fixed32s" had too many elements') - } - - obj.fixed32s.push(r2.fixed32()) - } - - break - } - case 10: { - const b = r.bytes() - const r2 = reader(b) - - while (r2.pos < r2.len) { - if (opts.limits?.fixed64s != null && obj.fixed64s.length === opts.limits.fixed64s) { - throw new MaxLengthError('Decode error - repeated field "fixed64s" had too many elements') - } - - obj.fixed64s.push(r2.fixed64()) - } - - break - } - case 11: { - const b = r.bytes() - const r2 = reader(b) - - while (r2.pos < r2.len) { - if (opts.limits?.sfixed32s != null && obj.sfixed32s.length === opts.limits.sfixed32s) { - throw new MaxLengthError('Decode error - repeated field "sfixed32s" had too many elements') - } - - obj.sfixed32s.push(r2.sfixed32()) - } - - break - } - case 12: { - const b = r.bytes() - const r2 = reader(b) - - while (r2.pos < r2.len) { - if (opts.limits?.sfixed64s != null && obj.sfixed64s.length === opts.limits.sfixed64s) { - throw new MaxLengthError('Decode error - repeated field "sfixed64s" had too many elements') - } - - obj.sfixed64s.push(r2.sfixed64()) - } - - break - } - case 13: { - const b = r.bytes() - const r2 = reader(b) - - while (r2.pos < r2.len) { - if (opts.limits?.bools != null && obj.bools.length === opts.limits.bools) { - throw new MaxLengthError('Decode error - repeated field "bools" had too many elements') - } - - obj.bools.push(r2.bool()) - } - - break - } - default: { - r.skipType(tag & 7) - break - } - } - } - - return obj - }, function * (r, length, prefix, opts = {}) { - const obj = { - doubles: 0, - floats: 0, - int32s: 0, - int64s: 0, - uint32s: 0, - uint64s: 0, - sint32s: 0, - sint64s: 0, - fixed32s: 0, - fixed64s: 0, - sfixed32s: 0, - sfixed64s: 0, - bools: 0 - } - - const end = length == null ? r.len : r.pos + length - - if (prefix !== '.') { - yield { - field: prefix.endsWith('.') ? prefix.substring(0, prefix.length - 1) : prefix, - type: 'start', - message: 'ExpandedTypes' - } - } - - while (r.pos < end) { - const tag = r.uint32() - - switch (tag >>> 3) { - case 1: { - const b = r.bytes() - const r2 = reader(b) - - while (r2.pos < r2.len) { - if (opts.limits?.doubles != null && obj.doubles === opts.limits.doubles) { - throw new MaxLengthError('Streaming decode error - repeated field "doubles" had too many elements') - } - - yield { - field: `${prefix}doubles[]`, - index: obj.doubles, - value: r2.double() - } - - obj.doubles++ - } - - break - } - case 2: { - const b = r.bytes() - const r2 = reader(b) - - while (r2.pos < r2.len) { - if (opts.limits?.floats != null && obj.floats === opts.limits.floats) { - throw new MaxLengthError('Streaming decode error - repeated field "floats" had too many elements') - } - - yield { - field: `${prefix}floats[]`, - index: obj.floats, - value: r2.float() - } - - obj.floats++ - } - - break - } - case 3: { - const b = r.bytes() - const r2 = reader(b) - - while (r2.pos < r2.len) { - if (opts.limits?.int32s != null && obj.int32s === opts.limits.int32s) { - throw new MaxLengthError('Streaming decode error - repeated field "int32s" had too many elements') - } - - yield { - field: `${prefix}int32s[]`, - index: obj.int32s, - value: r2.int32() - } - - obj.int32s++ - } - - break - } - case 4: { - const b = r.bytes() - const r2 = reader(b) - - while (r2.pos < r2.len) { - if (opts.limits?.int64s != null && obj.int64s === opts.limits.int64s) { - throw new MaxLengthError('Streaming decode error - repeated field "int64s" had too many elements') - } - - yield { - field: `${prefix}int64s[]`, - index: obj.int64s, - value: r2.int64() - } - - obj.int64s++ - } - - break - } - case 5: { - const b = r.bytes() - const r2 = reader(b) - - while (r2.pos < r2.len) { - if (opts.limits?.uint32s != null && obj.uint32s === opts.limits.uint32s) { - throw new MaxLengthError('Streaming decode error - repeated field "uint32s" had too many elements') - } - - yield { - field: `${prefix}uint32s[]`, - index: obj.uint32s, - value: r2.uint32() - } - - obj.uint32s++ - } - - break - } - case 6: { - const b = r.bytes() - const r2 = reader(b) - - while (r2.pos < r2.len) { - if (opts.limits?.uint64s != null && obj.uint64s === opts.limits.uint64s) { - throw new MaxLengthError('Streaming decode error - repeated field "uint64s" had too many elements') - } - - yield { - field: `${prefix}uint64s[]`, - index: obj.uint64s, - value: r2.uint64() - } - - obj.uint64s++ - } - - break - } - case 7: { - const b = r.bytes() - const r2 = reader(b) - - while (r2.pos < r2.len) { - if (opts.limits?.sint32s != null && obj.sint32s === opts.limits.sint32s) { - throw new MaxLengthError('Streaming decode error - repeated field "sint32s" had too many elements') - } - - yield { - field: `${prefix}sint32s[]`, - index: obj.sint32s, - value: r2.sint32() - } - - obj.sint32s++ - } - - break - } - case 8: { - const b = r.bytes() - const r2 = reader(b) - - while (r2.pos < r2.len) { - if (opts.limits?.sint64s != null && obj.sint64s === opts.limits.sint64s) { - throw new MaxLengthError('Streaming decode error - repeated field "sint64s" had too many elements') - } - - yield { - field: `${prefix}sint64s[]`, - index: obj.sint64s, - value: r2.sint64() - } - - obj.sint64s++ - } - - break - } - case 9: { - const b = r.bytes() - const r2 = reader(b) - - while (r2.pos < r2.len) { - if (opts.limits?.fixed32s != null && obj.fixed32s === opts.limits.fixed32s) { - throw new MaxLengthError('Streaming decode error - repeated field "fixed32s" had too many elements') - } - - yield { - field: `${prefix}fixed32s[]`, - index: obj.fixed32s, - value: r2.fixed32() - } - - obj.fixed32s++ - } - - break - } - case 10: { - const b = r.bytes() - const r2 = reader(b) - - while (r2.pos < r2.len) { - if (opts.limits?.fixed64s != null && obj.fixed64s === opts.limits.fixed64s) { - throw new MaxLengthError('Streaming decode error - repeated field "fixed64s" had too many elements') - } - - yield { - field: `${prefix}fixed64s[]`, - index: obj.fixed64s, - value: r2.fixed64() - } - - obj.fixed64s++ - } - - break - } - case 11: { - const b = r.bytes() - const r2 = reader(b) - - while (r2.pos < r2.len) { - if (opts.limits?.sfixed32s != null && obj.sfixed32s === opts.limits.sfixed32s) { - throw new MaxLengthError('Streaming decode error - repeated field "sfixed32s" had too many elements') - } - - yield { - field: `${prefix}sfixed32s[]`, - index: obj.sfixed32s, - value: r2.sfixed32() - } - - obj.sfixed32s++ - } - - break - } - case 12: { - const b = r.bytes() - const r2 = reader(b) - - while (r2.pos < r2.len) { - if (opts.limits?.sfixed64s != null && obj.sfixed64s === opts.limits.sfixed64s) { - throw new MaxLengthError('Streaming decode error - repeated field "sfixed64s" had too many elements') - } - - yield { - field: `${prefix}sfixed64s[]`, - index: obj.sfixed64s, - value: r2.sfixed64() - } - - obj.sfixed64s++ - } - - break - } - case 13: { - const b = r.bytes() - const r2 = reader(b) - - while (r2.pos < r2.len) { - if (opts.limits?.bools != null && obj.bools === opts.limits.bools) { - throw new MaxLengthError('Streaming decode error - repeated field "bools" had too many elements') - } - - yield { - field: `${prefix}bools[]`, - index: obj.bools, - value: r2.bool() - } - - obj.bools++ - } - - break - } - default: { - r.skipType(tag & 7) - break - } - } - } - - if (prefix !== '.') { - yield { - field: prefix.endsWith('.') ? prefix.substring(0, prefix.length - 1) : prefix, - type: 'end', - message: 'ExpandedTypes' - } - } - }) - } - - return _codec - } - - export interface ExpandedTypesDoublesFieldEvent { - field: '.doubles[]' - index: number - value: number - } - - export interface ExpandedTypesFloatsFieldEvent { - field: '.floats[]' - index: number - value: number - } - - export interface ExpandedTypesInt32sFieldEvent { - field: '.int32s[]' - index: number - value: number - } - - export interface ExpandedTypesInt64sFieldEvent { - field: '.int64s[]' - index: number - value: bigint - } - - export interface ExpandedTypesUint32sFieldEvent { - field: '.uint32s[]' - index: number - value: number - } - - export interface ExpandedTypesUint64sFieldEvent { - field: '.uint64s[]' - index: number - value: bigint - } - - export interface ExpandedTypesSint32sFieldEvent { - field: '.sint32s[]' - index: number - value: number - } - - export interface ExpandedTypesSint64sFieldEvent { - field: '.sint64s[]' - index: number - value: bigint - } - - export interface ExpandedTypesFixed32sFieldEvent { - field: '.fixed32s[]' - index: number - value: number - } - - export interface ExpandedTypesFixed64sFieldEvent { - field: '.fixed64s[]' - index: number - value: bigint - } - - export interface ExpandedTypesSfixed32sFieldEvent { - field: '.sfixed32s[]' - index: number - value: number - } - - export interface ExpandedTypesSfixed64sFieldEvent { - field: '.sfixed64s[]' - index: number - value: bigint - } - - export interface ExpandedTypesBoolsFieldEvent { - field: '.bools[]' - index: number - value: boolean - } - - export function encode (obj: ExpandedTypesInput): Uint8Array { - return encodeMessage(obj, ExpandedTypes.codec()) - } - - export function decode (buf: Uint8Array | Uint8ArrayList, opts?: DecodeOptions): ExpandedTypes { - return decodeMessage(buf, ExpandedTypes.codec(), opts) - } - - export function stream (buf: Uint8Array | Uint8ArrayList, opts?: DecodeOptions): Generator { - return streamMessage(buf, ExpandedTypes.codec(), opts) - } -} - -export interface NewOptionPackedTypes { - doubles: number[] - floats: number[] - int32s: number[] - int64s: bigint[] - uint32s: number[] - uint64s: bigint[] - sint32s: number[] - sint64s: bigint[] - fixed32s: number[] - fixed64s: bigint[] - sfixed32s: number[] - sfixed64s: bigint[] - bools: boolean[] -} - -export interface NewOptionPackedTypesInput { - doubles?: number[] - floats?: number[] - int32s?: number[] - int64s?: bigint[] - uint32s?: number[] - uint64s?: bigint[] - sint32s?: number[] - sint64s?: bigint[] - fixed32s?: number[] - fixed64s?: bigint[] - sfixed32s?: number[] - sfixed64s?: bigint[] - bools?: boolean[] -} - -export namespace NewOptionPackedTypes { - let _codec: Codec - - export const codec = (): Codec => { - if (_codec == null) { - _codec = message((obj, w, opts = {}) => { - if (opts.lengthDelimited !== false) { - w.fork() - } - - if (obj.doubles != null && obj.doubles.length > 0) { - w.uint32(10) - w.fork() - - for (const value of obj.doubles) { - w.double(value) - } - - w.ldelim() - } - - if (obj.floats != null && obj.floats.length > 0) { - w.uint32(18) - w.fork() - - for (const value of obj.floats) { - w.float(value) - } - - w.ldelim() - } - - if (obj.int32s != null && obj.int32s.length > 0) { - w.uint32(26) - w.fork() - - for (const value of obj.int32s) { - w.int32(value) - } - - w.ldelim() - } - - if (obj.int64s != null && obj.int64s.length > 0) { - w.uint32(34) - w.fork() - - for (const value of obj.int64s) { - w.int64(value) - } - - w.ldelim() - } - - if (obj.uint32s != null && obj.uint32s.length > 0) { - w.uint32(42) - w.fork() - - for (const value of obj.uint32s) { - w.uint32(value) - } - - w.ldelim() - } - - if (obj.uint64s != null && obj.uint64s.length > 0) { - w.uint32(50) - w.fork() - - for (const value of obj.uint64s) { - w.uint64(value) - } - - w.ldelim() - } - - if (obj.sint32s != null && obj.sint32s.length > 0) { - w.uint32(58) - w.fork() - - for (const value of obj.sint32s) { - w.sint32(value) - } - - w.ldelim() - } - - if (obj.sint64s != null && obj.sint64s.length > 0) { - w.uint32(66) - w.fork() - - for (const value of obj.sint64s) { - w.sint64(value) - } - - w.ldelim() - } - - if (obj.fixed32s != null && obj.fixed32s.length > 0) { - w.uint32(74) - w.fork() - - for (const value of obj.fixed32s) { - w.fixed32(value) - } - - w.ldelim() - } - - if (obj.fixed64s != null && obj.fixed64s.length > 0) { - w.uint32(82) - w.fork() - - for (const value of obj.fixed64s) { - w.fixed64(value) - } - - w.ldelim() - } - - if (obj.sfixed32s != null && obj.sfixed32s.length > 0) { - w.uint32(90) - w.fork() - - for (const value of obj.sfixed32s) { - w.sfixed32(value) - } - - w.ldelim() - } - - if (obj.sfixed64s != null && obj.sfixed64s.length > 0) { - w.uint32(98) - w.fork() - - for (const value of obj.sfixed64s) { - w.sfixed64(value) - } - - w.ldelim() - } - - if (obj.bools != null && obj.bools.length > 0) { - w.uint32(106) - w.fork() - - for (const value of obj.bools) { - w.bool(value) - } - - w.ldelim() - } - - if (opts.lengthDelimited !== false) { - w.ldelim() - } - }, (r, length, opts = {}) => { - const obj: any = { - doubles: [], - floats: [], - int32s: [], - int64s: [], - uint32s: [], - uint64s: [], - sint32s: [], - sint64s: [], - fixed32s: [], - fixed64s: [], - sfixed32s: [], - sfixed64s: [], - bools: [] - } - - const end = length == null ? r.len : r.pos + length - - while (r.pos < end) { - const tag = r.uint32() - - switch (tag >>> 3) { - case 1: { - const b = r.bytes() - const r2 = reader(b) - - while (r2.pos < r2.len) { - if (opts.limits?.doubles != null && obj.doubles.length === opts.limits.doubles) { - throw new MaxLengthError('Decode error - repeated field "doubles" had too many elements') - } - - obj.doubles.push(r2.double()) - } - - break - } - case 2: { - const b = r.bytes() - const r2 = reader(b) - - while (r2.pos < r2.len) { - if (opts.limits?.floats != null && obj.floats.length === opts.limits.floats) { - throw new MaxLengthError('Decode error - repeated field "floats" had too many elements') - } - - obj.floats.push(r2.float()) - } - - break - } - case 3: { - const b = r.bytes() - const r2 = reader(b) - - while (r2.pos < r2.len) { - if (opts.limits?.int32s != null && obj.int32s.length === opts.limits.int32s) { - throw new MaxLengthError('Decode error - repeated field "int32s" had too many elements') - } - - obj.int32s.push(r2.int32()) - } - - break - } - case 4: { - const b = r.bytes() - const r2 = reader(b) - - while (r2.pos < r2.len) { - if (opts.limits?.int64s != null && obj.int64s.length === opts.limits.int64s) { - throw new MaxLengthError('Decode error - repeated field "int64s" had too many elements') - } - - obj.int64s.push(r2.int64()) - } - - break - } - case 5: { - const b = r.bytes() - const r2 = reader(b) - - while (r2.pos < r2.len) { - if (opts.limits?.uint32s != null && obj.uint32s.length === opts.limits.uint32s) { - throw new MaxLengthError('Decode error - repeated field "uint32s" had too many elements') - } - - obj.uint32s.push(r2.uint32()) - } - - break - } - case 6: { - const b = r.bytes() - const r2 = reader(b) - - while (r2.pos < r2.len) { - if (opts.limits?.uint64s != null && obj.uint64s.length === opts.limits.uint64s) { - throw new MaxLengthError('Decode error - repeated field "uint64s" had too many elements') - } - - obj.uint64s.push(r2.uint64()) - } - - break - } - case 7: { - const b = r.bytes() - const r2 = reader(b) - - while (r2.pos < r2.len) { - if (opts.limits?.sint32s != null && obj.sint32s.length === opts.limits.sint32s) { - throw new MaxLengthError('Decode error - repeated field "sint32s" had too many elements') - } - - obj.sint32s.push(r2.sint32()) - } - - break - } - case 8: { - const b = r.bytes() - const r2 = reader(b) - - while (r2.pos < r2.len) { - if (opts.limits?.sint64s != null && obj.sint64s.length === opts.limits.sint64s) { - throw new MaxLengthError('Decode error - repeated field "sint64s" had too many elements') - } - - obj.sint64s.push(r2.sint64()) - } - - break - } - case 9: { - const b = r.bytes() - const r2 = reader(b) - - while (r2.pos < r2.len) { - if (opts.limits?.fixed32s != null && obj.fixed32s.length === opts.limits.fixed32s) { - throw new MaxLengthError('Decode error - repeated field "fixed32s" had too many elements') - } - - obj.fixed32s.push(r2.fixed32()) - } - - break - } - case 10: { - const b = r.bytes() - const r2 = reader(b) - - while (r2.pos < r2.len) { - if (opts.limits?.fixed64s != null && obj.fixed64s.length === opts.limits.fixed64s) { - throw new MaxLengthError('Decode error - repeated field "fixed64s" had too many elements') - } - - obj.fixed64s.push(r2.fixed64()) - } - - break - } - case 11: { - const b = r.bytes() - const r2 = reader(b) - - while (r2.pos < r2.len) { - if (opts.limits?.sfixed32s != null && obj.sfixed32s.length === opts.limits.sfixed32s) { - throw new MaxLengthError('Decode error - repeated field "sfixed32s" had too many elements') - } - - obj.sfixed32s.push(r2.sfixed32()) - } - - break - } - case 12: { - const b = r.bytes() - const r2 = reader(b) - - while (r2.pos < r2.len) { - if (opts.limits?.sfixed64s != null && obj.sfixed64s.length === opts.limits.sfixed64s) { - throw new MaxLengthError('Decode error - repeated field "sfixed64s" had too many elements') - } - - obj.sfixed64s.push(r2.sfixed64()) - } - - break - } - case 13: { - const b = r.bytes() - const r2 = reader(b) - - while (r2.pos < r2.len) { - if (opts.limits?.bools != null && obj.bools.length === opts.limits.bools) { - throw new MaxLengthError('Decode error - repeated field "bools" had too many elements') - } - - obj.bools.push(r2.bool()) - } - - break - } - default: { - r.skipType(tag & 7) - break - } - } - } - - return obj - }, function * (r, length, prefix, opts = {}) { - const obj = { - doubles: 0, - floats: 0, - int32s: 0, - int64s: 0, - uint32s: 0, - uint64s: 0, - sint32s: 0, - sint64s: 0, - fixed32s: 0, - fixed64s: 0, - sfixed32s: 0, - sfixed64s: 0, - bools: 0 - } - - const end = length == null ? r.len : r.pos + length - - if (prefix !== '.') { - yield { - field: prefix.endsWith('.') ? prefix.substring(0, prefix.length - 1) : prefix, - type: 'start', - message: 'NewOptionPackedTypes' - } - } - - while (r.pos < end) { - const tag = r.uint32() - - switch (tag >>> 3) { - case 1: { - const b = r.bytes() - const r2 = reader(b) - - while (r2.pos < r2.len) { - if (opts.limits?.doubles != null && obj.doubles === opts.limits.doubles) { - throw new MaxLengthError('Streaming decode error - repeated field "doubles" had too many elements') - } - - yield { - field: `${prefix}doubles[]`, - index: obj.doubles, - value: r2.double() - } - - obj.doubles++ - } - - break - } - case 2: { - const b = r.bytes() - const r2 = reader(b) - - while (r2.pos < r2.len) { - if (opts.limits?.floats != null && obj.floats === opts.limits.floats) { - throw new MaxLengthError('Streaming decode error - repeated field "floats" had too many elements') - } - - yield { - field: `${prefix}floats[]`, - index: obj.floats, - value: r2.float() - } - - obj.floats++ - } - - break - } - case 3: { - const b = r.bytes() - const r2 = reader(b) - - while (r2.pos < r2.len) { - if (opts.limits?.int32s != null && obj.int32s === opts.limits.int32s) { - throw new MaxLengthError('Streaming decode error - repeated field "int32s" had too many elements') - } - - yield { - field: `${prefix}int32s[]`, - index: obj.int32s, - value: r2.int32() - } - - obj.int32s++ - } - - break - } - case 4: { - const b = r.bytes() - const r2 = reader(b) - - while (r2.pos < r2.len) { - if (opts.limits?.int64s != null && obj.int64s === opts.limits.int64s) { - throw new MaxLengthError('Streaming decode error - repeated field "int64s" had too many elements') - } - - yield { - field: `${prefix}int64s[]`, - index: obj.int64s, - value: r2.int64() - } - - obj.int64s++ - } - - break - } - case 5: { - const b = r.bytes() - const r2 = reader(b) - - while (r2.pos < r2.len) { - if (opts.limits?.uint32s != null && obj.uint32s === opts.limits.uint32s) { - throw new MaxLengthError('Streaming decode error - repeated field "uint32s" had too many elements') - } - - yield { - field: `${prefix}uint32s[]`, - index: obj.uint32s, - value: r2.uint32() - } - - obj.uint32s++ - } - - break - } - case 6: { - const b = r.bytes() - const r2 = reader(b) - - while (r2.pos < r2.len) { - if (opts.limits?.uint64s != null && obj.uint64s === opts.limits.uint64s) { - throw new MaxLengthError('Streaming decode error - repeated field "uint64s" had too many elements') - } - - yield { - field: `${prefix}uint64s[]`, - index: obj.uint64s, - value: r2.uint64() - } - - obj.uint64s++ - } - - break - } - case 7: { - const b = r.bytes() - const r2 = reader(b) - - while (r2.pos < r2.len) { - if (opts.limits?.sint32s != null && obj.sint32s === opts.limits.sint32s) { - throw new MaxLengthError('Streaming decode error - repeated field "sint32s" had too many elements') - } - - yield { - field: `${prefix}sint32s[]`, - index: obj.sint32s, - value: r2.sint32() - } - - obj.sint32s++ - } - - break - } - case 8: { - const b = r.bytes() - const r2 = reader(b) - - while (r2.pos < r2.len) { - if (opts.limits?.sint64s != null && obj.sint64s === opts.limits.sint64s) { - throw new MaxLengthError('Streaming decode error - repeated field "sint64s" had too many elements') - } - - yield { - field: `${prefix}sint64s[]`, - index: obj.sint64s, - value: r2.sint64() - } - - obj.sint64s++ - } - - break - } - case 9: { - const b = r.bytes() - const r2 = reader(b) - - while (r2.pos < r2.len) { - if (opts.limits?.fixed32s != null && obj.fixed32s === opts.limits.fixed32s) { - throw new MaxLengthError('Streaming decode error - repeated field "fixed32s" had too many elements') - } - - yield { - field: `${prefix}fixed32s[]`, - index: obj.fixed32s, - value: r2.fixed32() - } - - obj.fixed32s++ - } - - break - } - case 10: { - const b = r.bytes() - const r2 = reader(b) - - while (r2.pos < r2.len) { - if (opts.limits?.fixed64s != null && obj.fixed64s === opts.limits.fixed64s) { - throw new MaxLengthError('Streaming decode error - repeated field "fixed64s" had too many elements') - } - - yield { - field: `${prefix}fixed64s[]`, - index: obj.fixed64s, - value: r2.fixed64() - } - - obj.fixed64s++ - } - - break - } - case 11: { - const b = r.bytes() - const r2 = reader(b) - - while (r2.pos < r2.len) { - if (opts.limits?.sfixed32s != null && obj.sfixed32s === opts.limits.sfixed32s) { - throw new MaxLengthError('Streaming decode error - repeated field "sfixed32s" had too many elements') - } - - yield { - field: `${prefix}sfixed32s[]`, - index: obj.sfixed32s, - value: r2.sfixed32() - } - - obj.sfixed32s++ - } - - break - } - case 12: { - const b = r.bytes() - const r2 = reader(b) - - while (r2.pos < r2.len) { - if (opts.limits?.sfixed64s != null && obj.sfixed64s === opts.limits.sfixed64s) { - throw new MaxLengthError('Streaming decode error - repeated field "sfixed64s" had too many elements') - } - - yield { - field: `${prefix}sfixed64s[]`, - index: obj.sfixed64s, - value: r2.sfixed64() - } - - obj.sfixed64s++ - } - - break - } - case 13: { - const b = r.bytes() - const r2 = reader(b) - - while (r2.pos < r2.len) { - if (opts.limits?.bools != null && obj.bools === opts.limits.bools) { - throw new MaxLengthError('Streaming decode error - repeated field "bools" had too many elements') - } - - yield { - field: `${prefix}bools[]`, - index: obj.bools, - value: r2.bool() - } - - obj.bools++ - } - - break - } - default: { - r.skipType(tag & 7) - break - } - } - } - - if (prefix !== '.') { - yield { - field: prefix.endsWith('.') ? prefix.substring(0, prefix.length - 1) : prefix, - type: 'end', - message: 'NewOptionPackedTypes' - } - } - }) - } - - return _codec - } - - export interface NewOptionPackedTypesDoublesFieldEvent { - field: '.doubles[]' - index: number - value: number - } - - export interface NewOptionPackedTypesFloatsFieldEvent { - field: '.floats[]' - index: number - value: number - } - - export interface NewOptionPackedTypesInt32sFieldEvent { - field: '.int32s[]' - index: number - value: number - } - - export interface NewOptionPackedTypesInt64sFieldEvent { - field: '.int64s[]' - index: number - value: bigint - } - - export interface NewOptionPackedTypesUint32sFieldEvent { - field: '.uint32s[]' - index: number - value: number - } - - export interface NewOptionPackedTypesUint64sFieldEvent { - field: '.uint64s[]' - index: number - value: bigint - } - - export interface NewOptionPackedTypesSint32sFieldEvent { - field: '.sint32s[]' - index: number - value: number - } - - export interface NewOptionPackedTypesSint64sFieldEvent { - field: '.sint64s[]' - index: number - value: bigint - } - - export interface NewOptionPackedTypesFixed32sFieldEvent { - field: '.fixed32s[]' - index: number - value: number - } - - export interface NewOptionPackedTypesFixed64sFieldEvent { - field: '.fixed64s[]' - index: number - value: bigint - } - - export interface NewOptionPackedTypesSfixed32sFieldEvent { - field: '.sfixed32s[]' - index: number - value: number - } - - export interface NewOptionPackedTypesSfixed64sFieldEvent { - field: '.sfixed64s[]' - index: number - value: bigint - } - - export interface NewOptionPackedTypesBoolsFieldEvent { - field: '.bools[]' - index: number - value: boolean - } - - export function encode (obj: NewOptionPackedTypesInput): Uint8Array { - return encodeMessage(obj, NewOptionPackedTypes.codec()) - } - - export function decode (buf: Uint8Array | Uint8ArrayList, opts?: DecodeOptions): NewOptionPackedTypes { - return decodeMessage(buf, NewOptionPackedTypes.codec(), opts) - } - - export function stream (buf: Uint8Array | Uint8ArrayList, opts?: DecodeOptions): Generator { - return streamMessage(buf, NewOptionPackedTypes.codec(), opts) - } -} - -export interface NewOptionExpandedTypes { - doubles: number[] - floats: number[] - int32s: number[] - int64s: bigint[] - uint32s: number[] - uint64s: bigint[] - sint32s: number[] - sint64s: bigint[] - fixed32s: number[] - fixed64s: bigint[] - sfixed32s: number[] - sfixed64s: bigint[] - bools: boolean[] -} - -export interface NewOptionExpandedTypesInput { - doubles?: number[] - floats?: number[] - int32s?: number[] - int64s?: bigint[] - uint32s?: number[] - uint64s?: bigint[] - sint32s?: number[] - sint64s?: bigint[] - fixed32s?: number[] - fixed64s?: bigint[] - sfixed32s?: number[] - sfixed64s?: bigint[] - bools?: boolean[] -} - -export namespace NewOptionExpandedTypes { - let _codec: Codec - - export const codec = (): Codec => { - if (_codec == null) { - _codec = message((obj, w, opts = {}) => { + _codec = message((obj, w, opts = {}) => { if (opts.lengthDelimited !== false) { w.fork() } @@ -3675,7 +2069,7 @@ export namespace NewOptionExpandedTypes { yield { field: prefix.endsWith('.') ? prefix.substring(0, prefix.length - 1) : prefix, type: 'start', - message: 'NewOptionExpandedTypes' + message: 'OptionExpandedTypes' } } @@ -3889,7 +2283,7 @@ export namespace NewOptionExpandedTypes { yield { field: prefix.endsWith('.') ? prefix.substring(0, prefix.length - 1) : prefix, type: 'end', - message: 'NewOptionExpandedTypes' + message: 'OptionExpandedTypes' } } }) @@ -3898,93 +2292,93 @@ export namespace NewOptionExpandedTypes { return _codec } - export interface NewOptionExpandedTypesDoublesFieldEvent { + export interface OptionExpandedTypesDoublesFieldEvent { field: '.doubles[]' index: number value: number } - export interface NewOptionExpandedTypesFloatsFieldEvent { + export interface OptionExpandedTypesFloatsFieldEvent { field: '.floats[]' index: number value: number } - export interface NewOptionExpandedTypesInt32sFieldEvent { + export interface OptionExpandedTypesInt32sFieldEvent { field: '.int32s[]' index: number value: number } - export interface NewOptionExpandedTypesInt64sFieldEvent { + export interface OptionExpandedTypesInt64sFieldEvent { field: '.int64s[]' index: number value: bigint } - export interface NewOptionExpandedTypesUint32sFieldEvent { + export interface OptionExpandedTypesUint32sFieldEvent { field: '.uint32s[]' index: number value: number } - export interface NewOptionExpandedTypesUint64sFieldEvent { + export interface OptionExpandedTypesUint64sFieldEvent { field: '.uint64s[]' index: number value: bigint } - export interface NewOptionExpandedTypesSint32sFieldEvent { + export interface OptionExpandedTypesSint32sFieldEvent { field: '.sint32s[]' index: number value: number } - export interface NewOptionExpandedTypesSint64sFieldEvent { + export interface OptionExpandedTypesSint64sFieldEvent { field: '.sint64s[]' index: number value: bigint } - export interface NewOptionExpandedTypesFixed32sFieldEvent { + export interface OptionExpandedTypesFixed32sFieldEvent { field: '.fixed32s[]' index: number value: number } - export interface NewOptionExpandedTypesFixed64sFieldEvent { + export interface OptionExpandedTypesFixed64sFieldEvent { field: '.fixed64s[]' index: number value: bigint } - export interface NewOptionExpandedTypesSfixed32sFieldEvent { + export interface OptionExpandedTypesSfixed32sFieldEvent { field: '.sfixed32s[]' index: number value: number } - export interface NewOptionExpandedTypesSfixed64sFieldEvent { + export interface OptionExpandedTypesSfixed64sFieldEvent { field: '.sfixed64s[]' index: number value: bigint } - export interface NewOptionExpandedTypesBoolsFieldEvent { + export interface OptionExpandedTypesBoolsFieldEvent { field: '.bools[]' index: number value: boolean } - export function encode (obj: NewOptionExpandedTypesInput): Uint8Array { - return encodeMessage(obj, NewOptionExpandedTypes.codec()) + export function encode (obj: OptionExpandedTypesInput): Uint8Array { + return encodeMessage(obj, OptionExpandedTypes.codec()) } - export function decode (buf: Uint8Array | Uint8ArrayList, opts?: DecodeOptions): NewOptionExpandedTypes { - return decodeMessage(buf, NewOptionExpandedTypes.codec(), opts) + export function decode (buf: Uint8Array | Uint8ArrayList, opts?: DecodeOptions): OptionExpandedTypes { + return decodeMessage(buf, OptionExpandedTypes.codec(), opts) } - export function stream (buf: Uint8Array | Uint8ArrayList, opts?: DecodeOptions): Generator { - return streamMessage(buf, NewOptionExpandedTypes.codec(), opts) + export function stream (buf: Uint8Array | Uint8ArrayList, opts?: DecodeOptions): Generator { + return streamMessage(buf, OptionExpandedTypes.codec(), opts) } } diff --git a/packages/protons/test/packed.spec.ts b/packages/protons/test/packed.spec.ts index 996c6f9..8609560 100644 --- a/packages/protons/test/packed.spec.ts +++ b/packages/protons/test/packed.spec.ts @@ -3,7 +3,8 @@ import all from 'it-all' import { fromString as uint8ArrayFromString } from 'uint8arrays/from-string' import { toString as uint8ArrayToString } from 'uint8arrays/to-string' import { GlobalPacked } from './fixtures/packed-global.ts' -import { DefaultPackedTypes, ExpandedTypes, NewOptionExpandedTypes, NewOptionPackedTypes, PackedTypes, SpecPacked } from './fixtures/packed.ts' +import { Proto2DefaultPackedTypes, Proto2ExpandedTypes, Proto2PackedTypes } from './fixtures/packed-proto2.ts' +import { DefaultPackedTypes, OptionExpandedTypes, OptionPackedTypes, SpecPacked } from './fixtures/packed.ts' import { testEncodings } from './utils/compat.ts' describe('packed', () => { @@ -51,7 +52,6 @@ describe('packed', () => { }]) }) - // protobufjs doesn't pack by default for proto3 and later but it should? it('should encode default packed types to same bytes as other implementations', () => { const obj: DefaultPackedTypes = { doubles: [1.0, 2.0, 3.0], @@ -72,9 +72,8 @@ describe('packed', () => { testEncodings(obj, DefaultPackedTypes, './test/fixtures/packed.proto', 'DefaultPackedTypes') }) - // protobufjs doesn't understand [packed=true|false] - it('should encode packed types to same bytes as other implementations', () => { - const obj: PackedTypes = { + it('should encode new option packed types to same bytes as other implementations', () => { + const obj: OptionPackedTypes = { doubles: [1.0, 2.0, 3.0], floats: [1.0, 2.0, 3.0], int32s: [1, 2, 3], @@ -90,11 +89,11 @@ describe('packed', () => { bools: [true, true, false] } - testEncodings(obj, PackedTypes, './test/fixtures/packed.proto', 'PackedTypes') + testEncodings(obj, OptionPackedTypes, './test/fixtures/packed.proto', 'OptionPackedTypes') }) - it('should encode expanded types to same bytes as other implementations', () => { - const obj: ExpandedTypes = { + it('should encode new option expanded types to same bytes as other implementations', () => { + const obj: OptionExpandedTypes = { doubles: [1.0, 2.0, 3.0], floats: [1.0, 2.0, 3.0], int32s: [1, 2, 3], @@ -110,77 +109,101 @@ describe('packed', () => { bools: [true, true, false] } - testEncodings(obj, ExpandedTypes, './test/fixtures/packed.proto', 'ExpandedTypes') + testEncodings(obj, OptionExpandedTypes, './test/fixtures/packed.proto', 'OptionExpandedTypes') }) - it('should encode new option packed types to same bytes as other implementations', () => { - const obj: NewOptionPackedTypes = { - doubles: [1.0, 2.0, 3.0], - floats: [1.0, 2.0, 3.0], - int32s: [1, 2, 3], - int64s: [1n, 2n, 3n], - uint32s: [1, 2, 3], - uint64s: [1n, 2n, 3n], - sint32s: [1, 2, 3], - sint64s: [1n, 2n, 3n], - fixed32s: [1, 2, 3], - fixed64s: [1n, 2n, 3n], - sfixed32s: [1, 2, 3], - sfixed64s: [1n, 2n, 3n], - bools: [true, true, false] - } - - testEncodings(obj, NewOptionPackedTypes, './test/fixtures/packed.proto', 'NewOptionPackedTypes') + describe('global options', () => { + it('should respect global options', () => { + expect(uint8ArrayToString(GlobalPacked.encode({ + expanded: [1, 1] + }), 'base16')).to.equal('08010801', 'file-level repeated-field-encoding set to expanded ignored') + + expect(uint8ArrayToString(GlobalPacked.encode({ + packedOldOption: [1, 1] + }), 'base16')).to.equal('10011001', 'old field-level repeated-field-encoding set to packed ignored') + + expect(uint8ArrayToString(GlobalPacked.encode({ + expandedOldOption: [1, 1] + }), 'base16')).to.equal('18011801', 'old field-level repeated-field-encoding set to expanded ignored') + + expect(uint8ArrayToString(GlobalPacked.encode({ + packedNewOption: [1, 1] + }), 'base16')).to.equal('22020101', 'new field-level repeated-field-encoding set to packed ignored') + + expect(uint8ArrayToString(GlobalPacked.encode({ + expandedNewOption: [1, 1] + }), 'base16')).to.equal('28012801', 'new field-level repeated-field-encoding set to expanded ignored') + + testEncodings({ + expanded: [1, 1], + // protobufjs ignores proto2-style [packed=false] field override + packedOldOption: [], + expandedOldOption: [1, 1], + packedNewOption: [1, 1], + expandedNewOption: [1, 1] + }, GlobalPacked, './test/fixtures/packed-global.proto', 'GlobalPacked') + }) }) - it('should encode new option expanded types to same bytes as other implementations', () => { - const obj: NewOptionExpandedTypes = { - doubles: [1.0, 2.0, 3.0], - floats: [1.0, 2.0, 3.0], - int32s: [1, 2, 3], - int64s: [1n, 2n, 3n], - uint32s: [1, 2, 3], - uint64s: [1n, 2n, 3n], - sint32s: [1, 2, 3], - sint64s: [1n, 2n, 3n], - fixed32s: [1, 2, 3], - fixed64s: [1n, 2n, 3n], - sfixed32s: [1, 2, 3], - sfixed64s: [1n, 2n, 3n], - bools: [true, true, false] - } + describe('proto2', () => { + it('should encode default packed types to same bytes as other implementations', () => { + const obj: Proto2DefaultPackedTypes = { + doubles: [1.0, 2.0, 3.0], + floats: [1.0, 2.0, 3.0], + int32s: [1, 2, 3], + int64s: [1n, 2n, 3n], + uint32s: [1, 2, 3], + uint64s: [1n, 2n, 3n], + sint32s: [1, 2, 3], + sint64s: [1n, 2n, 3n], + fixed32s: [1, 2, 3], + fixed64s: [1n, 2n, 3n], + sfixed32s: [1, 2, 3], + sfixed64s: [1n, 2n, 3n], + bools: [true, true, false] + } + + testEncodings(obj, Proto2DefaultPackedTypes, './test/fixtures/packed-proto2.proto', 'Proto2DefaultPackedTypes') + }) - testEncodings(obj, NewOptionExpandedTypes, './test/fixtures/packed.proto', 'NewOptionExpandedTypes') - }) + it('should encode packed types to same bytes as other implementations', () => { + const obj: Proto2PackedTypes = { + doubles: [1.0, 2.0, 3.0], + floats: [1.0, 2.0, 3.0], + int32s: [1, 2, 3], + int64s: [1n, 2n, 3n], + uint32s: [1, 2, 3], + uint64s: [1n, 2n, 3n], + sint32s: [1, 2, 3], + sint64s: [1n, 2n, 3n], + fixed32s: [1, 2, 3], + fixed64s: [1n, 2n, 3n], + sfixed32s: [1, 2, 3], + sfixed64s: [1n, 2n, 3n], + bools: [true, true, false] + } + + testEncodings(obj, Proto2PackedTypes, './test/fixtures/packed-proto2.proto', 'Proto2PackedTypes') + }) - it('should respect global options', () => { - expect(uint8ArrayToString(GlobalPacked.encode({ - expanded: [1, 1] - }), 'base16')).to.equal('08010801', 'file-level repeated-field-encoding set to expanded ignored') - - expect(uint8ArrayToString(GlobalPacked.encode({ - packedOldOption: [1, 1] - }), 'base16')).to.equal('10011001', 'old field-level repeated-field-encoding set to packed ignored') - - expect(uint8ArrayToString(GlobalPacked.encode({ - expandedOldOption: [1, 1] - }), 'base16')).to.equal('18011801', 'old field-level repeated-field-encoding set to expanded ignored') - - expect(uint8ArrayToString(GlobalPacked.encode({ - packedNewOption: [1, 1] - }), 'base16')).to.equal('22020101', 'new field-level repeated-field-encoding set to packed ignored') - - expect(uint8ArrayToString(GlobalPacked.encode({ - expandedNewOption: [1, 1] - }), 'base16')).to.equal('28012801', 'new field-level repeated-field-encoding set to expanded ignored') - - testEncodings({ - expanded: [1, 1], - // protobufjs ignores proto2-style [packed=false] field override - packedOldOption: [], - expandedOldOption: [1, 1], - packedNewOption: [1, 1], - expandedNewOption: [1, 1] - }, GlobalPacked, './test/fixtures/packed-global.proto', 'GlobalPacked') + it('should encode expanded types to same bytes as other implementations', () => { + const obj: Proto2ExpandedTypes = { + doubles: [1.0, 2.0, 3.0], + floats: [1.0, 2.0, 3.0], + int32s: [1, 2, 3], + int64s: [1n, 2n, 3n], + uint32s: [1, 2, 3], + uint64s: [1n, 2n, 3n], + sint32s: [1, 2, 3], + sint64s: [1n, 2n, 3n], + fixed32s: [1, 2, 3], + fixed64s: [1n, 2n, 3n], + sfixed32s: [1, 2, 3], + sfixed64s: [1n, 2n, 3n], + bools: [true, true, false] + } + + testEncodings(obj, Proto2ExpandedTypes, './test/fixtures/packed-proto2.proto', 'Proto2ExpandedTypes') + }) }) }) From 44a79f705d1a12bb52a750a5366c75703c17e23d Mon Sep 17 00:00:00 2001 From: achingbrain Date: Fri, 18 Sep 2026 10:06:38 +0300 Subject: [PATCH 5/6] chore: add more tests --- packages/protons/test/packed.spec.ts | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/packages/protons/test/packed.spec.ts b/packages/protons/test/packed.spec.ts index 8609560..f00d62b 100644 --- a/packages/protons/test/packed.spec.ts +++ b/packages/protons/test/packed.spec.ts @@ -8,6 +8,13 @@ import { DefaultPackedTypes, OptionExpandedTypes, OptionPackedTypes, SpecPacked import { testEncodings } from './utils/compat.ts' describe('packed', () => { + it('should encode packed by default', () => { + const buf = DefaultPackedTypes.encode({ + int32s: [1, 2, 3] + }) + expect(uint8ArrayToString(buf, 'base16')).to.equal('1a03010203') + }) + it('encodes the spec example', () => { const obj: SpecPacked = { str: 'hello', @@ -146,6 +153,13 @@ describe('packed', () => { }) describe('proto2', () => { + it('should encode expanded by default', () => { + const buf = Proto2DefaultPackedTypes.encode({ + int32s: [1, 2, 3] + }) + expect(uint8ArrayToString(buf, 'base16')).to.equal('180118021803') + }) + it('should encode default packed types to same bytes as other implementations', () => { const obj: Proto2DefaultPackedTypes = { doubles: [1.0, 2.0, 3.0], From 5fbf2c1f1cedc0d49b56ab9623650a5cb6c10023 Mon Sep 17 00:00:00 2001 From: achingbrain Date: Fri, 18 Sep 2026 10:06:53 +0300 Subject: [PATCH 6/6] chore: linting --- packages/protons/test/packed.spec.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/protons/test/packed.spec.ts b/packages/protons/test/packed.spec.ts index f00d62b..9f5fc01 100644 --- a/packages/protons/test/packed.spec.ts +++ b/packages/protons/test/packed.spec.ts @@ -9,11 +9,11 @@ import { testEncodings } from './utils/compat.ts' describe('packed', () => { it('should encode packed by default', () => { - const buf = DefaultPackedTypes.encode({ - int32s: [1, 2, 3] - }) - expect(uint8ArrayToString(buf, 'base16')).to.equal('1a03010203') + const buf = DefaultPackedTypes.encode({ + int32s: [1, 2, 3] }) + expect(uint8ArrayToString(buf, 'base16')).to.equal('1a03010203') + }) it('encodes the spec example', () => { const obj: SpecPacked = {