From d8a0cf94fb3343cd4a583c0fd220a3db5084fec4 Mon Sep 17 00:00:00 2001 From: achingbrain Date: Fri, 18 Sep 2026 14:32:59 +0300 Subject: [PATCH 1/3] fix: support packed option in proto3 Default to proto3 when no edition is present. Proto2 gets picked up ok but proto3 seems to get ignored. --- packages/protons/package.json | 2 +- packages/protons/src/fields/array-field.ts | 16 +++++++++++++--- packages/protons/src/fields/field.ts | 2 +- packages/protons/src/types/enum.ts | 1 + packages/protons/src/types/message.ts | 2 +- packages/protons/src/types/module.ts | 1 + 6 files changed, 18 insertions(+), 6 deletions(-) diff --git a/packages/protons/package.json b/packages/protons/package.json index af45049..539dcaf 100644 --- a/packages/protons/package.json +++ b/packages/protons/package.json @@ -137,7 +137,7 @@ }, "dependencies": { "meow": "^14.1.0", - "protobufjs-cli": "^2.6.1", + "protobufjs-cli": "^2.7.0", "protons-runtime": "^8.0.0" }, "devDependencies": { diff --git a/packages/protons/src/fields/array-field.ts b/packages/protons/src/fields/array-field.ts index 31051d4..23eebc1 100644 --- a/packages/protons/src/fields/array-field.ts +++ b/packages/protons/src/fields/array-field.ts @@ -70,18 +70,28 @@ export class ArrayField extends Field { const type = parent.findType(this.type).pbType const supportsPacked = PACKABLE_TYPES.indexOf(type) !== -1 + console.info(parent) + if (parent.def.edition === 'proto2') { this.packed = false - // check user overrides for field encoding + // check only old-school user overrides for field encoding if (usePackedEncoding(def.options, parent.def.options)) { this.packed = true } + } else if (parent.def.edition === 'proto3') { + // the default from editions onwards + this.packed = supportsPacked + + // check old and new-school user overrides for field encoding + if (def.options?.packed === false || useExpandedEncoding(def.options, parent.def.options)) { + this.packed = false + } } else { - // the default from protobuf3 onwards + // the default from editions onwards this.packed = supportsPacked - // check user overrides for field encoding + // check only new-school user overrides for field encoding if (useExpandedEncoding(def.options, parent.def.options)) { this.packed = false } diff --git a/packages/protons/src/fields/field.ts b/packages/protons/src/fields/field.ts index fa8dfd2..9bd6d45 100644 --- a/packages/protons/src/fields/field.ts +++ b/packages/protons/src/fields/field.ts @@ -145,7 +145,7 @@ export class Field implements MessageField { console.info(`[WARN] ${message}`) } } - } else { + } else if (parent.def.edition != null && parent.def.edition !== 'proto3') { if (def.options?.packed != null) { const message = `field "${name}" has the packed=${def.options.packed} option, this is unsupported in edition="${parent.def.edition}". Please use features.repeated_field_encoding=${def.options?.packed === true ? 'PACKED' : 'EXPANDED'} instead - see https://protobuf.dev/editions/features/#repeated_field_encoding` diff --git a/packages/protons/src/types/enum.ts b/packages/protons/src/types/enum.ts index 7e2c2a9..a0eacf8 100644 --- a/packages/protons/src/types/enum.ts +++ b/packages/protons/src/types/enum.ts @@ -4,6 +4,7 @@ import type { Parent, Type, TypeCodec } from './index.ts' import type { Field } from '../fields/field.ts' export interface EnumDef { + edition: string values: Record } diff --git a/packages/protons/src/types/message.ts b/packages/protons/src/types/message.ts index c9e4e4c..6abc1fb 100644 --- a/packages/protons/src/types/message.ts +++ b/packages/protons/src/types/message.ts @@ -70,7 +70,7 @@ export class Message implements Type { const mapEntryType = `${this.pbType}$${fieldName}Entry` def.nested[mapEntryType] = { - edition: def.edition, + edition: def.edition || 'proto3', fields: { key: { type: fieldDef.keyType, diff --git a/packages/protons/src/types/module.ts b/packages/protons/src/types/module.ts index 23b16de..461ad43 100644 --- a/packages/protons/src/types/module.ts +++ b/packages/protons/src/types/module.ts @@ -106,6 +106,7 @@ export class Module { for (const [name, def] of Object.entries(defs)) { let type: Message | Enum + def.edition ??= 'proto3' if (isEnumDef(def)) { type = new Enum(name, { From f7b0bb85d6943365e7749d43c5f73fdd36a11697 Mon Sep 17 00:00:00 2001 From: achingbrain Date: Fri, 18 Sep 2026 14:40:00 +0300 Subject: [PATCH 2/3] chore: linting --- packages/protons/src/fields/array-field.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/packages/protons/src/fields/array-field.ts b/packages/protons/src/fields/array-field.ts index 23eebc1..53eea31 100644 --- a/packages/protons/src/fields/array-field.ts +++ b/packages/protons/src/fields/array-field.ts @@ -70,8 +70,6 @@ export class ArrayField extends Field { const type = parent.findType(this.type).pbType const supportsPacked = PACKABLE_TYPES.indexOf(type) !== -1 - console.info(parent) - if (parent.def.edition === 'proto2') { this.packed = false From 0b81248d79b57c18360768b27d5102e79c965eb9 Mon Sep 17 00:00:00 2001 From: achingbrain Date: Fri, 18 Sep 2026 14:42:32 +0300 Subject: [PATCH 3/3] chore: simplify --- packages/protons/src/fields/array-field.ts | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/packages/protons/src/fields/array-field.ts b/packages/protons/src/fields/array-field.ts index 53eea31..41b709f 100644 --- a/packages/protons/src/fields/array-field.ts +++ b/packages/protons/src/fields/array-field.ts @@ -77,17 +77,14 @@ export class ArrayField extends Field { if (usePackedEncoding(def.options, parent.def.options)) { this.packed = true } - } else if (parent.def.edition === 'proto3') { + } else { // the default from editions onwards this.packed = supportsPacked - // check old and new-school user overrides for field encoding - if (def.options?.packed === false || useExpandedEncoding(def.options, parent.def.options)) { + // support older `packed` option in proto3 only + if (parent.def.edition === 'proto3' && def.options?.packed === false) { this.packed = false } - } else { - // the default from editions onwards - this.packed = supportsPacked // check only new-school user overrides for field encoding if (useExpandedEncoding(def.options, parent.def.options)) {