Skip to content

Fix field type inference when FieldDescriptorProto.type is unset#1369

Open
jakewisse wants to merge 2 commits intobufbuild:mainfrom
jakewisse:bugfix/file-descriptor-proto-type-optional
Open

Fix field type inference when FieldDescriptorProto.type is unset#1369
jakewisse wants to merge 2 commits intobufbuild:mainfrom
jakewisse:bugfix/file-descriptor-proto-type-optional

Conversation

@jakewisse
Copy link
Copy Markdown

@jakewisse jakewisse commented Mar 4, 2026

Some protobuf tooling (e.g. Confluent Schema Registry) omits the type field from FieldDescriptorProto when type_name is set. According to descriptor.proto, this is valid : "If type_name is set, this need not be set."

Because descriptor.proto is proto2, protobuf-es places the default value (TYPE_DOUBLE = 1) on the prototype. When type is absent from the wire data it is never set as an own property, and proto.type inherits the prototype default, causing message and enum fields to be misclassified as scalar.

This resolves the field type from the registry via type_name when type is not explicitly set. From there, we thread the resolved type through getFieldPresence(), isPackedField(), and isDelimitedEncoding() to avoid the same prototype fallback in those functions.

Fixes #1368.

@CLAassistant
Copy link
Copy Markdown

CLAassistant commented Mar 4, 2026

CLA assistant check
All committers have signed the CLA.

@timostamm
Copy link
Copy Markdown
Member

Thanks for the PR, Jake. Can you sign the CLA?

@jakewisse
Copy link
Copy Markdown
Author

@timostamm sorry for the delay here, I actually did sign it right away but for some reason CLA assistant would never sync to the PR… Every time I click the link to sign it shows as already signed to me.

Some protobuf tooling (e.g. Confluent Schema Registry) omits the `type`
field from FieldDescriptorProto when `type_name` is set. According to
[`descriptor.proto`][0], this is valid : "If type_name is set, this need not
be set."

Because descriptor.proto is proto2, protobuf-es places the default value
(TYPE_DOUBLE = 1) on the prototype. When `type` is absent from the wire
data it is never set as an own property, and `proto.type` inherits the
prototype default, causing message and enum fields to be misclassified
as scalar.

This resolves the field type from the registry via `type_name` when
`type` is not explicitly set. From there, thread the resolved type
through `getFieldPresence()`, `isPackedField()`, and
`isDelimitedEncoding()` to avoid the same prototype fallback in those
functions.

--
[0]: https://github.com/protocolbuffers/protobuf/blob/c223b2e1fa96feac05f275853e64a87993d557a2/src/google/protobuf/descriptor.proto#L295-L296
@jakewisse jakewisse force-pushed the bugfix/file-descriptor-proto-type-optional branch from e5d8be6 to 3cc7bec Compare March 30, 2026 18:51
@jakewisse
Copy link
Copy Markdown
Author

Ah, it was my fault. I created the commit using an email associated with a different Github account. Looks like it has synced properly now.

…perly

I can't find exactly where this changed in TS 5.0, but for some reason
in 5.0 and later using `assert.strictEqual(itemsField.fieldKind,
'list')` narrows the value to a `descFieldList`, whereas in 4.9 it
doesn't.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Fields are incorrectly classified as scalar when type omitted from FieldDescriptorProto

3 participants