From eab283ab76e20e432d34aaa76bd8d9affae721e4 Mon Sep 17 00:00:00 2001 From: Tatu Saloranta Date: Wed, 1 Jul 2026 13:51:11 -0700 Subject: [PATCH] Fix #73: (protobuf) Cannot resolve inner types in protoc definitions Backport of PR #656 (originally fixed on 3.x) to the 2.21 branch: resolve dot-notation references to nested message types (e.g. "OuterType.InnerType") in protoc schema definitions. --- .../protobuf/schema/TypeResolver.java | 26 ++++++++++++++++++- .../NestedTypeRef73Test.java} | 18 ++++--------- release-notes/CREDITS-2.x | 2 ++ release-notes/VERSION-2.x | 5 ++++ 4 files changed, 37 insertions(+), 14 deletions(-) rename protobuf/src/test/java/com/fasterxml/jackson/dataformat/protobuf/{tofix/GenerateNestedType73Test.java => schema/NestedTypeRef73Test.java} (60%) diff --git a/protobuf/src/main/java/com/fasterxml/jackson/dataformat/protobuf/schema/TypeResolver.java b/protobuf/src/main/java/com/fasterxml/jackson/dataformat/protobuf/schema/TypeResolver.java index ca0099ced..8a0e7d681 100644 --- a/protobuf/src/main/java/com/fasterxml/jackson/dataformat/protobuf/schema/TypeResolver.java +++ b/protobuf/src/main/java/com/fasterxml/jackson/dataformat/protobuf/schema/TypeResolver.java @@ -223,7 +223,31 @@ private ProtobufField _findAndResolve(FieldElement nativeField, String typeStr) if (nativeMt != null) { return new ProtobufField(nativeField, resolve(this, nativeMt)); } - return null; + // [dataformats-binary#73] Handle dot-notation references to nested message types + // (e.g. "OuterType.InnerType") + return _findDottedType(nativeField, typeStr); + } + + /** + * Try to resolve a dot-notation type reference (e.g. {@code "OuterType.InnerType"}) + * by navigating the message type hierarchy declared at this scope level. + */ + private ProtobufField _findDottedType(FieldElement nativeField, String typeStr) + { + int dotIx = typeStr.indexOf('.'); + if (dotIx <= 0) { + return null; + } + String outerName = typeStr.substring(0, dotIx); + String innerPath = typeStr.substring(dotIx + 1); + MessageElement outerMsg = _declaredMessageTypes.get(outerName); + if (outerMsg == null) { + return null; + } + // Create a resolver in the context of the outer type and recursively + // resolve the remaining path (handles arbitrary nesting depth) + TypeResolver outerResolver = TypeResolver.construct(this, outerName, outerMsg.nestedElements()); + return outerResolver._findAndResolve(nativeField, innerPath); } private StringBuilder _knownEnums(StringBuilder sb) { diff --git a/protobuf/src/test/java/com/fasterxml/jackson/dataformat/protobuf/tofix/GenerateNestedType73Test.java b/protobuf/src/test/java/com/fasterxml/jackson/dataformat/protobuf/schema/NestedTypeRef73Test.java similarity index 60% rename from protobuf/src/test/java/com/fasterxml/jackson/dataformat/protobuf/tofix/GenerateNestedType73Test.java rename to protobuf/src/test/java/com/fasterxml/jackson/dataformat/protobuf/schema/NestedTypeRef73Test.java index e56cb8936..c659628b5 100644 --- a/protobuf/src/test/java/com/fasterxml/jackson/dataformat/protobuf/tofix/GenerateNestedType73Test.java +++ b/protobuf/src/test/java/com/fasterxml/jackson/dataformat/protobuf/schema/NestedTypeRef73Test.java @@ -1,4 +1,4 @@ -package com.fasterxml.jackson.dataformat.protobuf.tofix; +package com.fasterxml.jackson.dataformat.protobuf.schema; import java.io.StringReader; @@ -6,25 +6,17 @@ import com.fasterxml.jackson.dataformat.protobuf.ProtobufMapper; import com.fasterxml.jackson.dataformat.protobuf.ProtobufTestBase; -import com.fasterxml.jackson.dataformat.protobuf.schema.ProtobufSchema; -import com.fasterxml.jackson.dataformat.protobuf.testutil.failure.JacksonTestFailureExpected; import static org.junit.jupiter.api.Assertions.assertNotNull; -public class GenerateNestedType73Test extends ProtobufTestBase +// [dataformats-binary#73] +public class NestedTypeRef73Test extends ProtobufTestBase { - /* - /********************************************************** - /* Test methods - /********************************************************** - */ - final ProtobufMapper MAPPER = new ProtobufMapper(); - // [dataformats-binary#68] - @JacksonTestFailureExpected + // [dataformats-binary#73]: dot-notation reference to a nested message type @Test - public void testNestedTypes() throws Exception + public void testNestedTypeRefViaRootType() throws Exception { final String SCHEMA_STR = " package mypackage;\n" diff --git a/release-notes/CREDITS-2.x b/release-notes/CREDITS-2.x index b94a4cd14..e898ce9df 100644 --- a/release-notes/CREDITS-2.x +++ b/release-notes/CREDITS-2.x @@ -19,6 +19,8 @@ Kenji Noguchi (knoguchi@github) * Reported #70 (protobuf), contributed fix: Can't deserialize packed repeated field (2.8.9) +* Reported #73: (protobuf) Cannot resolve inner types in protoc definitions + (2.21.5) marsqing@github diff --git a/release-notes/VERSION-2.x b/release-notes/VERSION-2.x index c8f7e7a32..2d118e9d7 100644 --- a/release-notes/VERSION-2.x +++ b/release-notes/VERSION-2.x @@ -14,6 +14,11 @@ Active maintainers: === Releases === ------------------------------------------------------------------------ +2.21.5 (not yet released) + +#73: (protobuf) Cannot resolve inner types in protoc definitions + (reported by Kenji N) + 2.21.4 (28-May-2026) #691: (cbor) Add parameterized tests covering all ASCII-optimization exit paths in CBORParser