Open
Conversation
Implemented comprehensive support for protobuf-generated classes with smart accessor detection and code generation. Core Features: 1. Protobuf Getter Recognition - getXxxList() → property "xxx" (repeated fields) - getXxxMap() → property "xxx" (map fields) 2. Repeated Field Support - Detects addXxx() methods for repeated fields - Generates loop-based adder calls instead of setters - Example: addItem(item) for List<Item> items 3. Map Field Support (NEW) - Added PUTTER accessor type for map operations - Detects putXxx(K, V) methods for map entries - Detects putAllXxx(Map) for bulk operations - Generates entry iteration with putter calls Implementation Details: - Extended MethodType enum with PUTTER type - Extended AccessorType enum with PUTTER type - Created ProtobufAccessorNamingStrategy for protobuf patterns - Added getPutterForType() method in Type.java - Created PutterWrapper and PutterWrapper.ftl for code generation - Updated PropertyMapping to handle PUTTER accessor type - Integrated putter selection into getPropertyWriteAccessors() Technical Changes: - processor/src/main/java/org/mapstruct/ap/spi/MethodType.java - processor/src/main/java/org/mapstruct/ap/internal/util/accessor/AccessorType.java - processor/src/main/java/org/mapstruct/ap/spi/ProtobufAccessorNamingStrategy.java (new) - processor/src/main/java/org/mapstruct/ap/internal/util/AccessorNamingUtils.java - processor/src/main/java/org/mapstruct/ap/internal/util/Filters.java - processor/src/main/java/org/mapstruct/ap/internal/model/common/Type.java - processor/src/main/java/org/mapstruct/ap/internal/model/PropertyMapping.java - processor/src/main/java/org/mapstruct/ap/internal/model/assignment/PutterWrapper.java (new) - processor/src/main/resources/.../assignment/PutterWrapper.ftl (new) Backward Compatibility: - All changes are additive and non-breaking - Default behavior preserved for non-protobuf classes - Protobuf support activated via ProtobufAccessorNamingStrategy 🤖 Generated with Claude Code Co-Authored-By: Claude <noreply@anthropic.com> refactor: Improve ProtobufAccessorNamingStrategy to only apply to MessageOrBuilder types Based on the reference implementation from mapstruct-examples, this commit adds proper type checking to ensure protobuf-specific logic is only applied to Protocol Buffers generated classes. Key Improvements: 1. MessageOrBuilder Type Detection - Initialize protobufMessageOrBuilderType in init() method - Check isProtobufType() before applying any protobuf-specific logic - Only classes implementing com.google.protobuf.MessageOrBuilder get special treatment 2. Protobuf Method Exclusions - Exclude getXxxBuilderList() methods (internal builder lists) - Exclude getXxxValueList() methods (internal value lists) - Exclude getAllFields() method (protobuf metadata) - Exclude methods with protobuf internal types as parameters - Exclude remove(int) methods (protobuf list manipulation) - Exclude mergeFrom() methods (protobuf internal) 3. Enhanced getElementName() - Append "List" suffix only for protobuf types - Matches protobuf convention: addItem() -> itemsList property - Append "Map" suffix for putter methods: putAttribute() -> attributesMap 4. Backward Compatibility - Non-protobuf classes use default behavior - All checks delegate to super methods first - Only add protobuf-specific filters on top Implementation follows the pattern from: https://github.com/mapstruct/mapstruct-examples/tree/main/mapstruct-on-gradle-protobuf3 🤖 Generated with Claude Code Co-Authored-By: Claude <noreply@anthropic.com> Refactor: Treat protobuf map putters as ADDER type Simplified architecture by removing the separate PUTTER method type and treating map putter methods (e.g., putXxx(key, value)) as ADDER type instead. This reduces code complexity while maintaining the same functionality for protobuf map field mapping. Changes: - Removed PUTTER from MethodType and AccessorType enums - Updated ProtobufAccessorNamingStrategy to return ADDER for putter methods - Updated AccessorNamingUtils to accept 1 or 2 parameters for adders - Removed putterMethodsIn from Filters - Simplified Type.java by removing getPutters/getPutterForType methods - Updated getAdderForType to handle both collections and maps - Simplified PropertyMapping by removing assignToPlainViaPutter - Updated assignToPlainViaAdder to handle maps with PutterWrapper 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> test: Add tests for Protocol Buffers (protobuf) support Added comprehensive tests to verify ProtobufAccessorNamingStrategy functionality: Test Structure: - Created mock com.google.protobuf.MessageOrBuilder interface for testing - Created protobuf-style source classes with getXxxList() and getXxxMap() patterns - Created target DTOs with standard JavaBeans accessors and adder/putter methods - Registered ProtobufAccessorNamingStrategy in test resources META-INF/services Tests: - SimpleProtobufTest: Tests basic repeated field mapping (getItemsList -> addItem) - ProtobufTest: Tests both repeated and map field mappings (currently partially working) The tests verify that: 1. getXxxList() is recognized as getter for "xxx" property (repeated fields) 2. getXxxMap() is recognized as getter for "xxx" property (map fields) 3. addXxx() adder methods are used for repeated fields 4. putXxx() putter methods are used for map fields Note: SimpleProtobufTest passes successfully, demonstrating that repeated field support is working correctly with ProtobufAccessorNamingStrategy. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> add docs ref ref rm doc revert revert revert cpl error no adder for pb no adder for pb handle enum done not support byte[] add ProtobufEnumConversion google/type pkg rm DateTime support adjust format rm unused code add protobufTest add protobufTest done ref ignore message set builder const fmt add headler inline ref it revert unnecessary changes revert unnecessary changes revert unnecessary changes revert unnecessary changes Add missing import
Author
|
@filiphr Do you have time to take a look at this PR? It would be amazing if MapStruct could provide first-class support for protobuf. |
|
@filiphr Yes it would be great if we could get built-in proto support for 1.7.0 - I would like to make use of this library within our team, but we are very careful with adding any additional dependency. And getting built-in support for proto is one of the features we would like for it to really being considered. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Overview
Adds built-in support for Protocol Buffers generated classes in MapStruct. No more
Key Changes
1. ProtobufAccessorNamingStrategy
Custom accessor naming strategy that handles Protobuf-specific patterns:
getXxxBytes(),getXxxCount(),getXxxOrBuilder(),getXxxValue())getXxxList()for repeated fieldsgetXxxMap()for map fieldsaddAllXxx()andputAllXxx()as setters for collections2. Type Conversions
Protobuf wrapper types ↔ Java primitives/objects:
BoolValue,StringValue,BytesValueInt32Value,Int64Value,UInt32Value,UInt64ValueFloatValue,DoubleValueByteString↔ byte arrayProtocolMessageEnum↔ int3. Built-in Mappings
Java time types ↔ Protobuf well-known/google.type:
Instant↔google.protobuf.TimestampDuration↔google.protobuf.DurationLocalDate↔google.type.DateLocalTime↔google.type.TimeOfDayDayOfWeek↔google.type.DayOfWeekMonth↔google.type.Monthclose #3073