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-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/package.json b/packages/protons/package.json index bcf01a6..f929edc 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 a947dba..31051d4 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,84 @@ 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' +] + +/** + * Detect proto3 (and later) expanded field override + */ +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 +} + +/** + * 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 - 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'] + + const type = parent.findType(this.type).pbType + const supportsPacked = PACKABLE_TYPES.indexOf(type) !== -1 + + 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) { + throw new Error(`Repeated field "${name}" of type "${type}" cannot be packed as it is not a non-string/byte scalar type`) + } } getDecoderInterfaceField (parent: Parent, indent = ''): string { @@ -45,6 +116,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}) { @@ -73,6 +158,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 @@ -103,6 +203,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/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 c122f89..1f604eb 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 { @@ -98,10 +99,12 @@ export class Field implements MessageField { public proto2Required: boolean public jsTypeOverride?: 'string' | 'number' public oneof?: string[] + 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 // 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/fields/map-field.ts b/packages/protons/src/fields/map-field.ts index 93044d2..6befbb8 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/enum.ts b/packages/protons/src/types/enum.ts index 3e9c56e..7e2c2a9 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.decode}.codec().decode(reader)` + getDecoder (field: Field, indent?: string, reader = 'r'): string { + return `${this.jsType.decode}.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.decode}.codec().decode(reader) +${indent} value: ${this.jsType.decode}.codec().decode(${reader}) ${indent} }` } return `yield { ${indent} field: ${prefix}, -${indent} value: ${this.jsType.decode}.codec().decode(reader) +${indent} value: ${this.jsType.decode}.codec().decode(${reader}) ${indent} }` } diff --git a/packages/protons/src/types/index.ts b/packages/protons/src/types/index.ts index 07e3fcd..e09088a 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 TypeCodec { @@ -11,8 +12,8 @@ export interface Type { jsType: TypeCodec 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 } @@ -24,3 +25,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 d948f84..66b7e43 100644 --- a/packages/protons/src/types/message.ts +++ b/packages/protons/src/types/message.ts @@ -27,6 +27,8 @@ function camelize (input: string): string { } export interface MessageDef { + edition: string + options?: Record fields?: Record oneofs?: Record nested?: Record @@ -42,7 +44,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: TypeCodec, def: MessageDef, parent: Parent) { @@ -68,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, @@ -169,7 +172,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) { @@ -188,10 +191,10 @@ ${indent} value: opts.limits?.${field.name}$value ${indent} }` } - return `${this.jsType.decode}.codec().decode(reader, reader.uint32()${opts})` + return `${this.jsType.decode}.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) { @@ -203,7 +206,7 @@ ${indent} }` ${indent} limits: opts.limits?.${field.name}$ ${indent} }` - return `for (const evt of ${this.jsType.decode}.codec().stream(reader, reader.uint32(), ${prefix}${opts})) { + return `for (const evt of ${this.jsType.decode}.codec().stream(${reader}, ${reader}.uint32(), ${prefix}${opts})) { ${indent} yield { ${indent} ...evt, ${indent} index: obj.${field.name} @@ -217,7 +220,7 @@ ${indent} value: opts.limits?.${field.name}$value ${indent} }` } - return `yield * ${this.jsType.decode}.codec().stream(reader, reader.uint32(), ${prefix}${opts})` + return `yield * ${this.jsType.decode}.codec().stream(${reader}, ${reader}.uint32(), ${prefix}${opts})` } getEncoder (field: Field, accessor: string): string { @@ -306,25 +309,25 @@ export interface ${this.pbType}Input { 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 { @@ -334,12 +337,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 e174e21..4ce648b 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, TypeCodec } 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 cfb20d1..e53c9a7 100644 --- a/packages/protons/test/fixtures/basic.ts +++ b/packages/protons/test/fixtures/basic.ts @@ -35,35 +35,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 { @@ -73,26 +73,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 } } @@ -151,25 +151,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 { @@ -179,12 +179,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 4c48eb2..89d434a 100644 --- a/packages/protons/test/fixtures/bitswap.ts +++ b/packages/protons/test/fixtures/bitswap.ts @@ -101,7 +101,7 @@ export namespace Message { if (opts.lengthDelimited !== false) { w.ldelim() } - }, (reader, length, opts = {}) => { + }, (r, length, opts = {}) => { const obj: any = { block: uint8ArrayAlloc(0), priority: 0, @@ -109,42 +109,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 { @@ -154,47 +154,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 } } @@ -275,16 +275,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: { @@ -292,29 +292,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 { @@ -324,8 +324,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: { @@ -333,7 +333,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 { @@ -349,12 +349,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 } } @@ -468,36 +468,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 { @@ -507,26 +507,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 } } @@ -617,36 +617,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 { @@ -656,26 +656,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 } } @@ -760,7 +760,7 @@ export namespace Message { if (opts.lengthDelimited !== false) { w.ldelim() } - }, (reader, length, opts = {}) => { + }, (r, length, opts = {}) => { const obj: any = { blocks: [], payload: [], @@ -768,14 +768,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 @@ -785,7 +785,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: { @@ -793,7 +793,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 @@ -803,31 +803,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 { @@ -837,12 +837,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 }) @@ -856,7 +856,7 @@ export namespace Message { yield { field: `${prefix}blocks[]`, index: obj.blocks, - value: reader.bytes() + value: r.bytes() } obj.blocks++ @@ -868,7 +868,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 { @@ -886,7 +886,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 { @@ -902,12 +902,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 2e17872..db6e254 100644 --- a/packages/protons/test/fixtures/circuit.ts +++ b/packages/protons/test/fixtures/circuit.ts @@ -117,20 +117,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: { @@ -138,23 +138,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 { @@ -164,14 +164,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 } @@ -183,7 +183,7 @@ export namespace CircuitRelay { yield { field: `${prefix}addrs[]`, index: obj.addrs, - value: reader.bytes() + value: r.bytes() } obj.addrs++ @@ -191,7 +191,7 @@ export namespace CircuitRelay { break } default: { - reader.skipType(tag & 7) + r.skipType(tag & 7) break } } @@ -266,45 +266,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 { @@ -314,26 +314,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 }) @@ -342,12 +342,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 39e56f1..536f5c8 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' @@ -58,36 +58,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 { @@ -97,26 +97,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 } } @@ -198,10 +198,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) { @@ -214,7 +218,7 @@ export namespace CustomOptionNumber { if (opts.lengthDelimited !== false) { w.ldelim() } - }, (reader, length, opts = {}) => { + }, (r, length, opts = {}) => { const obj: any = { num: 0, i64: 0, @@ -226,42 +230,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: { @@ -269,7 +279,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 } @@ -278,20 +288,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 { @@ -301,64 +311,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 } @@ -367,7 +382,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 } @@ -378,7 +393,7 @@ export namespace CustomOptionNumber { break } default: { - reader.skipType(tag & 7) + r.skipType(tag & 7) break } } @@ -508,36 +523,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 { @@ -547,26 +562,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 } } @@ -648,10 +663,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) { @@ -664,7 +683,7 @@ export namespace CustomOptionString { if (opts.lengthDelimited !== false) { w.ldelim() } - }, (reader, length, opts = {}) => { + }, (r, length, opts = {}) => { const obj: any = { num: 0, i64: '', @@ -676,42 +695,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: { @@ -719,7 +744,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 } @@ -728,20 +753,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 { @@ -751,64 +776,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 } @@ -817,7 +847,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 } @@ -828,7 +858,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 fa42eec..bf6e293 100644 --- a/packages/protons/test/fixtures/daemon.ts +++ b/packages/protons/test/fixtures/daemon.ts @@ -117,79 +117,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 { @@ -199,75 +199,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 } } @@ -611,42 +611,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 @@ -656,37 +656,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 { @@ -696,40 +696,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 }) @@ -740,7 +740,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 { @@ -754,21 +754,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 } } @@ -1027,20 +1027,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: { @@ -1048,23 +1048,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 { @@ -1074,14 +1074,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 } @@ -1093,7 +1093,7 @@ export namespace IdentifyResponse { yield { field: `${prefix}addrs[]`, index: obj.addrs, - value: reader.bytes() + value: r.bytes() } obj.addrs++ @@ -1101,7 +1101,7 @@ export namespace IdentifyResponse { break } default: { - reader.skipType(tag & 7) + r.skipType(tag & 7) break } } @@ -1186,20 +1186,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: { @@ -1207,27 +1207,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 { @@ -1237,14 +1237,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 } @@ -1256,7 +1256,7 @@ export namespace ConnectRequest { yield { field: `${prefix}addrs[]`, index: obj.addrs, - value: reader.bytes() + value: r.bytes() } obj.addrs++ @@ -1266,12 +1266,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 } } @@ -1361,20 +1361,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: { @@ -1382,27 +1382,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 { @@ -1412,14 +1412,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 } @@ -1431,7 +1431,7 @@ export namespace StreamOpenRequest { yield { field: `${prefix}proto[]`, index: obj.proto, - value: reader.string() + value: r.string() } obj.proto++ @@ -1441,12 +1441,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 } } @@ -1529,20 +1529,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: { @@ -1550,23 +1550,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 { @@ -1576,14 +1576,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 } @@ -1595,7 +1595,7 @@ export namespace StreamHandlerRequest { yield { field: `${prefix}proto[]`, index: obj.proto, - value: reader.string() + value: r.string() } obj.proto++ @@ -1603,7 +1603,7 @@ export namespace StreamHandlerRequest { break } default: { - reader.skipType(tag & 7) + r.skipType(tag & 7) break } } @@ -1672,31 +1672,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 { @@ -1706,19 +1706,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 } } @@ -1795,41 +1795,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 { @@ -1839,33 +1839,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 } } @@ -2010,55 +2010,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 { @@ -2068,61 +2068,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 } } @@ -2247,41 +2247,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 { @@ -2291,19 +2291,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 }) @@ -2312,12 +2312,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 } } @@ -2415,20 +2415,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: { @@ -2436,23 +2436,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 { @@ -2462,14 +2462,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 } @@ -2481,7 +2481,7 @@ export namespace PeerInfo { yield { field: `${prefix}addrs[]`, index: obj.addrs, - value: reader.bytes() + value: r.bytes() } obj.addrs++ @@ -2489,7 +2489,7 @@ export namespace PeerInfo { break } default: { - reader.skipType(tag & 7) + r.skipType(tag & 7) break } } @@ -2597,43 +2597,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 { @@ -2643,40 +2643,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 } } @@ -2754,31 +2754,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 { @@ -2788,19 +2788,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 } } @@ -2897,39 +2897,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 { @@ -2939,33 +2939,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 } } @@ -3075,27 +3075,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: { @@ -3103,31 +3103,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 { @@ -3137,28 +3137,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 } @@ -3170,7 +3170,7 @@ export namespace PSMessage { yield { field: `${prefix}topicIDs[]`, index: obj.topicIDs, - value: reader.string() + value: r.string() } obj.topicIDs++ @@ -3180,19 +3180,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 } } @@ -3292,16 +3292,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: { @@ -3309,7 +3309,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: { @@ -3317,24 +3317,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 { @@ -3344,8 +3344,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: { @@ -3356,7 +3356,7 @@ export namespace PSResponse { yield { field: `${prefix}topics[]`, index: obj.topics, - value: reader.string() + value: r.string() } obj.topics++ @@ -3371,7 +3371,7 @@ export namespace PSResponse { yield { field: `${prefix}peerIDs[]`, index: obj.peerIDs, - value: reader.bytes() + value: r.bytes() } obj.peerIDs++ @@ -3379,7 +3379,7 @@ export namespace PSResponse { break } default: { - reader.skipType(tag & 7) + r.skipType(tag & 7) break } } @@ -3483,24 +3483,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: { @@ -3508,23 +3508,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 { @@ -3534,21 +3534,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 } @@ -3560,7 +3560,7 @@ export namespace PeerstoreRequest { yield { field: `${prefix}protos[]`, index: obj.protos, - value: reader.string() + value: r.string() } obj.protos++ @@ -3568,7 +3568,7 @@ export namespace PeerstoreRequest { break } default: { - reader.skipType(tag & 7) + r.skipType(tag & 7) break } } @@ -3651,19 +3651,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 @@ -3673,23 +3673,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 { @@ -3699,12 +3699,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 }) @@ -3718,7 +3718,7 @@ export namespace PeerstoreResponse { yield { field: `${prefix}protos[]`, index: obj.protos, - value: reader.string() + value: r.string() } obj.protos++ @@ -3726,7 +3726,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 be998ac..2e8f4a6 100644 --- a/packages/protons/test/fixtures/dht.ts +++ b/packages/protons/test/fixtures/dht.ts @@ -56,45 +56,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 { @@ -104,47 +104,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 } } @@ -306,19 +306,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: { @@ -326,27 +326,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 { @@ -356,14 +356,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 } @@ -375,7 +375,7 @@ export namespace Message { yield { field: `${prefix}addrs[]`, index: obj.addrs, - value: reader.bytes() + value: r.bytes() } obj.addrs++ @@ -385,12 +385,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 } } @@ -484,32 +484,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: { @@ -517,7 +517,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 @@ -527,26 +527,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 { @@ -556,35 +556,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 } @@ -593,7 +593,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 { @@ -611,7 +611,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 { @@ -625,7 +625,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 81506d6..a4dd597 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' @@ -46,53 +46,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 { @@ -102,34 +112,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 } } @@ -222,36 +237,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 { @@ -261,26 +276,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 } } @@ -355,36 +370,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 { @@ -394,26 +409,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 } } @@ -488,36 +503,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 { @@ -527,26 +542,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 } } @@ -621,37 +636,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 { @@ -661,26 +676,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 } } @@ -771,36 +786,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 { @@ -810,26 +825,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 } } @@ -918,7 +933,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(), @@ -927,10 +942,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: { @@ -938,7 +953,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 } @@ -951,7 +966,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 } @@ -964,7 +979,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 } @@ -977,7 +992,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 } @@ -990,7 +1005,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 } @@ -999,14 +1014,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, @@ -1015,7 +1030,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 { @@ -1025,8 +1040,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: { @@ -1034,7 +1049,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 } @@ -1049,7 +1064,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 } @@ -1064,7 +1079,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 } @@ -1079,7 +1094,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 } @@ -1094,7 +1109,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 } @@ -1105,7 +1120,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 13a7ed8..0810f54 100644 --- a/packages/protons/test/fixtures/noise.ts +++ b/packages/protons/test/fixtures/noise.ts @@ -48,41 +48,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 { @@ -92,33 +92,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 } } @@ -177,25 +177,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 { @@ -205,12 +205,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 29f7488..3bd355d 100644 --- a/packages/protons/test/fixtures/oneof.ts +++ b/packages/protons/test/fixtures/oneof.ts @@ -90,39 +90,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 } } @@ -145,8 +145,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 { @@ -156,47 +156,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 } } @@ -307,7 +307,7 @@ export namespace MessageWithoutOneOfs { if (opts.lengthDelimited !== false) { w.ldelim() } - }, (reader, length, opts = {}) => { + }, (r, length, opts = {}) => { const obj: any = { fieldOne: '', fieldTwo: '', @@ -316,42 +316,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 { @@ -361,47 +361,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 70bb5b5..d432e64 100644 --- a/packages/protons/test/fixtures/optional.ts +++ b/packages/protons/test/fixtures/optional.ts @@ -53,33 +53,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 { @@ -89,26 +89,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 } } @@ -288,95 +288,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 { @@ -386,131 +386,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-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..8b78a2c --- /dev/null +++ b/packages/protons/test/fixtures/packed-global.ts @@ -0,0 +1,306 @@ +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 interface GlobalPackedInput { + 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: GlobalPackedInput): 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/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 new file mode 100644 index 0000000..44ad7b2 --- /dev/null +++ b/packages/protons/test/fixtures/packed.proto @@ -0,0 +1,54 @@ +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 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]; + 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 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]; + 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..b54006c --- /dev/null +++ b/packages/protons/test/fixtures/packed.ts @@ -0,0 +1,2384 @@ +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 interface SpecPackedInput { + 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: SpecPackedInput): 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 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 + + 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: DefaultPackedTypesInput): 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 OptionPackedTypes { + 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 OptionPackedTypesInput { + 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 OptionPackedTypes { + 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: 'OptionPackedTypes' + } + } + + 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: 'OptionPackedTypes' + } + } + }) + } + + return _codec + } + + export interface OptionPackedTypesDoublesFieldEvent { + field: '.doubles[]' + index: number + value: number + } + + export interface OptionPackedTypesFloatsFieldEvent { + field: '.floats[]' + index: number + value: number + } + + export interface OptionPackedTypesInt32sFieldEvent { + field: '.int32s[]' + index: number + value: number + } + + export interface OptionPackedTypesInt64sFieldEvent { + field: '.int64s[]' + index: number + value: bigint + } + + export interface OptionPackedTypesUint32sFieldEvent { + field: '.uint32s[]' + index: number + value: number + } + + export interface OptionPackedTypesUint64sFieldEvent { + field: '.uint64s[]' + index: number + value: bigint + } + + export interface OptionPackedTypesSint32sFieldEvent { + field: '.sint32s[]' + index: number + value: number + } + + export interface OptionPackedTypesSint64sFieldEvent { + field: '.sint64s[]' + index: number + value: bigint + } + + export interface OptionPackedTypesFixed32sFieldEvent { + field: '.fixed32s[]' + index: number + value: number + } + + export interface OptionPackedTypesFixed64sFieldEvent { + field: '.fixed64s[]' + index: number + value: bigint + } + + export interface OptionPackedTypesSfixed32sFieldEvent { + field: '.sfixed32s[]' + index: number + value: number + } + + export interface OptionPackedTypesSfixed64sFieldEvent { + field: '.sfixed64s[]' + index: number + value: bigint + } + + export interface OptionPackedTypesBoolsFieldEvent { + field: '.bools[]' + index: number + value: boolean + } + + export function encode (obj: OptionPackedTypesInput): Uint8Array { + return encodeMessage(obj, OptionPackedTypes.codec()) + } + + 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, OptionPackedTypes.codec(), opts) + } +} + +export interface OptionExpandedTypes { + 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 OptionExpandedTypesInput { + 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 OptionExpandedTypes { + 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: 'OptionExpandedTypes' + } + } + + 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: 'OptionExpandedTypes' + } + } + }) + } + + return _codec + } + + export interface OptionExpandedTypesDoublesFieldEvent { + field: '.doubles[]' + index: number + value: number + } + + export interface OptionExpandedTypesFloatsFieldEvent { + field: '.floats[]' + index: number + value: number + } + + export interface OptionExpandedTypesInt32sFieldEvent { + field: '.int32s[]' + index: number + value: number + } + + export interface OptionExpandedTypesInt64sFieldEvent { + field: '.int64s[]' + index: number + value: bigint + } + + export interface OptionExpandedTypesUint32sFieldEvent { + field: '.uint32s[]' + index: number + value: number + } + + export interface OptionExpandedTypesUint64sFieldEvent { + field: '.uint64s[]' + index: number + value: bigint + } + + export interface OptionExpandedTypesSint32sFieldEvent { + field: '.sint32s[]' + index: number + value: number + } + + export interface OptionExpandedTypesSint64sFieldEvent { + field: '.sint64s[]' + index: number + value: bigint + } + + export interface OptionExpandedTypesFixed32sFieldEvent { + field: '.fixed32s[]' + index: number + value: number + } + + export interface OptionExpandedTypesFixed64sFieldEvent { + field: '.fixed64s[]' + index: number + value: bigint + } + + export interface OptionExpandedTypesSfixed32sFieldEvent { + field: '.sfixed32s[]' + index: number + value: number + } + + export interface OptionExpandedTypesSfixed64sFieldEvent { + field: '.sfixed64s[]' + index: number + value: bigint + } + + export interface OptionExpandedTypesBoolsFieldEvent { + field: '.bools[]' + index: number + value: boolean + } + + export function encode (obj: OptionExpandedTypesInput): Uint8Array { + return encodeMessage(obj, OptionExpandedTypes.codec()) + } + + 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, OptionExpandedTypes.codec(), opts) + } +} diff --git a/packages/protons/test/fixtures/peer.ts b/packages/protons/test/fixtures/peer.ts index f2f43e9..b1c1a03 100644 --- a/packages/protons/test/fixtures/peer.ts +++ b/packages/protons/test/fixtures/peer.ts @@ -63,17 +63,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: { @@ -81,7 +81,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 @@ -91,7 +91,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: { @@ -99,35 +99,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 { @@ -137,8 +137,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: { @@ -146,7 +146,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 { @@ -167,7 +167,7 @@ export namespace Peer { yield { field: `${prefix}protocols[]`, index: obj.protocols, - value: reader.string() + value: r.string() } obj.protocols++ @@ -179,7 +179,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 { @@ -195,19 +195,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 } } @@ -340,35 +340,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 { @@ -378,26 +378,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 } } @@ -472,36 +472,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 { @@ -511,26 +511,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 014113d..0dd746d 100644 --- a/packages/protons/test/fixtures/proto2.ts +++ b/packages/protons/test/fixtures/proto2.ts @@ -26,31 +26,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 { @@ -60,19 +60,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 c6c79d8..0829f45 100644 --- a/packages/protons/test/fixtures/protons-options.ts +++ b/packages/protons/test/fixtures/protons-options.ts @@ -30,15 +30,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: { @@ -50,23 +50,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 { @@ -76,8 +76,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: { @@ -92,7 +92,7 @@ export namespace MessageWithSizeLimitedRepeatedField { yield { field: `${prefix}repeatedField[]`, index: obj.repeatedField, - value: reader.string() + value: r.string() } obj.repeatedField++ @@ -100,7 +100,7 @@ export namespace MessageWithSizeLimitedRepeatedField { break } default: { - reader.skipType(tag & 7) + r.skipType(tag & 7) break } } @@ -180,36 +180,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 { @@ -219,26 +219,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 } } @@ -299,15 +299,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: { @@ -319,7 +319,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 } @@ -328,19 +328,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 { @@ -350,8 +350,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: { @@ -363,7 +363,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 } @@ -374,7 +374,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 de8b711..213ddd7 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' @@ -37,15 +37,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: { @@ -53,27 +53,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 { @@ -83,8 +83,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: { @@ -95,7 +95,7 @@ export namespace SubSubMessage { yield { field: `${prefix}foo[]`, index: obj.foo, - value: reader.string() + value: r.string() } obj.foo++ @@ -105,12 +105,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 } } @@ -204,16 +204,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: { @@ -221,15 +221,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 @@ -239,26 +239,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 { @@ -268,8 +268,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: { @@ -280,7 +280,7 @@ export namespace SubMessage { yield { field: `${prefix}foo[]`, index: obj.foo, - value: reader.string() + value: r.string() } obj.foo++ @@ -290,12 +290,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 }) @@ -306,7 +306,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 { @@ -320,7 +320,7 @@ export namespace SubMessage { break } default: { - reader.skipType(tag & 7) + r.skipType(tag & 7) break } } @@ -437,17 +437,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) { @@ -470,37 +478,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: { @@ -508,37 +528,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 { @@ -548,41 +568,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 } @@ -591,7 +621,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 { @@ -605,7 +635,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 }) @@ -614,12 +644,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 1f931a3..570092b 100644 --- a/packages/protons/test/fixtures/singular.ts +++ b/packages/protons/test/fixtures/singular.ts @@ -54,36 +54,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 { @@ -93,26 +93,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 } } @@ -292,7 +292,7 @@ export namespace Singular { if (opts.lengthDelimited !== false) { w.ldelim() } - }, (reader, length, opts = {}) => { + }, (r, length, opts = {}) => { const obj: any = { double: 0, float: 0, @@ -312,92 +312,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 { @@ -407,131 +407,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 e07c504..5d3be29 100644 --- a/packages/protons/test/fixtures/streaming.ts +++ b/packages/protons/test/fixtures/streaming.ts @@ -44,23 +44,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: { @@ -68,23 +68,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 { @@ -94,21 +94,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 } @@ -120,7 +120,7 @@ export namespace MessageWithArrayField { yield { field: `${prefix}arr[]`, index: obj.arr, - value: reader.string() + value: r.string() } obj.arr++ @@ -128,7 +128,7 @@ export namespace MessageWithArrayField { break } default: { - reader.skipType(tag & 7) + r.skipType(tag & 7) break } } @@ -202,31 +202,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 { @@ -236,19 +236,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 } } @@ -318,37 +318,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 { @@ -358,26 +358,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 } } @@ -462,37 +462,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 { @@ -502,26 +502,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 } } @@ -623,20 +623,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: { @@ -644,25 +644,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 { @@ -672,14 +672,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 } @@ -688,7 +688,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 { @@ -702,7 +702,7 @@ export namespace MessageWithRepeatedMessage { break } default: { - reader.skipType(tag & 7) + r.skipType(tag & 7) break } } @@ -803,37 +803,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 { @@ -843,26 +843,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 } } @@ -938,20 +938,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: { @@ -959,7 +959,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 } @@ -968,19 +968,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 { @@ -990,14 +990,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 } @@ -1006,7 +1006,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 } @@ -1017,7 +1017,7 @@ export namespace MessageWithMapMessage { break } default: { - reader.skipType(tag & 7) + r.skipType(tag & 7) break } } @@ -1118,36 +1118,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 { @@ -1157,26 +1157,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 } } @@ -1242,20 +1242,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: { @@ -1263,7 +1263,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 } @@ -1272,19 +1272,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 { @@ -1294,14 +1294,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 } @@ -1310,7 +1310,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 } @@ -1321,7 +1321,7 @@ export namespace MessageWithPrimitiveMap { break } default: { - reader.skipType(tag & 7) + r.skipType(tag & 7) break } } @@ -1417,20 +1417,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: { @@ -1438,23 +1438,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 { @@ -1464,14 +1464,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 } @@ -1483,7 +1483,7 @@ export namespace MessageWithRepeatedEnums { yield { field: `${prefix}enums[]`, index: obj.enums, - value: ENUM.codec().decode(reader) + value: ENUM.codec().decode(r) } obj.enums++ @@ -1491,7 +1491,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 d726b53..61e4443 100644 --- a/packages/protons/test/fixtures/test.ts +++ b/packages/protons/test/fixtures/test.ts @@ -44,31 +44,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 { @@ -78,19 +78,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 } } @@ -274,67 +274,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 @@ -344,39 +344,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 { @@ -386,96 +386,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 }) @@ -489,7 +489,7 @@ export namespace AllTheTypes { yield { field: `${prefix}field14[]`, index: obj.field14, - value: reader.string() + value: r.string() } obj.field14++ @@ -499,33 +499,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..9f5fc01 --- /dev/null +++ b/packages/protons/test/packed.spec.ts @@ -0,0 +1,223 @@ +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 { 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', () => { + 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', + 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 + }]) + }) + + 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') + }) + + 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], + 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, OptionPackedTypes, './test/fixtures/packed.proto', 'OptionPackedTypes') + }) + + 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], + 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, OptionExpandedTypes, './test/fixtures/packed.proto', 'OptionExpandedTypes') + }) + + 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') + }) + }) + + 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], + 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') + }) + + 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 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') + }) + }) +}) 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) +}