Skip to content

Support map fields in the schema adapter - #3756

Open
oldergod wants to merge 6 commits into
bquenaudon/schema-adapter-packedfrom
bquenaudon/schema-adapter-maps
Open

oldergod wants to merge 6 commits into
bquenaudon/schema-adapter-packedfrom
bquenaudon/schema-adapter-maps

Conversation

@oldergod

@oldergod oldergod commented Nov 5, 2026 •

Copy link
Copy Markdown
Member

Schema.protoAdapter threw UnsupportedOperationException for any message with a map field.
The value adapter asked the factory for an adapter of the map type itself.
This change uses the map's value type, as the key adapter already uses the key type.
The model shape is a Map of keys to values under the field name, as the old ignored mapTest expected.

Map entries without a value decode to the identity value, as in generated adapters.
The schema enum adapter now uses the constant with tag 0 as its identity, as generated enum adapters do.
So a missing enum value decodes to the zero constant.
Wire requires enum map values to define 0 as the first constant, so this constant always exists for maps.
google.protobuf.NullValue decodes to null, so the runtime map adapter rejected valid NullValue map entries with "Map entry with null value".
This failed in generated Kotlin and Java code too.
The map adapter now accepts a null value only when the value adapter is ProtoAdapter.STRUCT_NULL.

Tests compare map bytes with protobuf-java DynamicMessage in proto2 and proto3, and mapTest is enabled again.
StructTest round trips a NullValue map entry through generated Kotlin and Java code and Schema.protoAdapter, and compares the bytes with protoc.
This PR is stacked on #3749.

Release note: Schema.protoAdapter now supports map fields.
The identity of a schema enum adapter is now the name of its constant with tag 0, or null if there is none.
Generated code and Schema.protoAdapter now decode map<K, google.protobuf.NullValue> entries.

The dynamic adapter threw for map fields because it asked for an adapter of the map type.
Use the map's value type for the value adapter, as the key adapter already uses its key type.
Enable the map round-trip test and compare map bytes with protobuf-java.
Map entries without a value threw in the schema adapter when the value was an enum.
Give the map value adapter the enum's zero constant as identity, as generated adapters do.
The zero identity for enum map values replaced built-in adapters such as NullValue.
Only give the identity to schema enum adapters, so NullValue still rejects nonzero values.
@oldergod
oldergod marked this pull request as ready for review November 5, 2026 13:26
Generated enum adapters use the constant with tag 0 as identity.
The schema enum adapter now does the same, so map values no longer need a separate adapter.
@oldergod
oldergod force-pushed the bquenaudon/schema-adapter-maps branch from 6a6f7fc to 25f0587 Compare November 9, 2026 16:33
`google.protobuf.NullValue` decodes to null, so the map adapter rejected valid entries with "Map entry with null value".
The map adapter now accepts a null value when the value adapter is `STRUCT_NULL`.
This fixes generated Kotlin and Java code and `Schema.protoAdapter`.
@oldergod
oldergod force-pushed the bquenaudon/schema-adapter-packed branch from 83eb52d to 27099c0 Compare November 9, 2026 17:35
@oldergod
oldergod force-pushed the bquenaudon/schema-adapter-maps branch from aba79f3 to 675d6d1 Compare November 9, 2026 17:35

This branch has not been deployed

No deployments
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.

1 participant