Filling up a map field in Proto using reflection A

2019-07-28 17:19发布

I am trying to write a module that will get a Message.Builder and a Map from field name to value and will fill the Builder with the values.

All works well until I encounter a map field ( using Proto3 ).

I get that for a specific message whose fields I know I can do:

builder.b.putAll<MapeFieldName>( map ),

But how do I use the Proto reflection API to achieve the same.

The MapEntry doc says: "In reflection API, map fields will be treated as repeated message fields and each map entry is accessed as a message." But I don't quite get what that means.

1条回答
Deceive 欺骗
2楼-- · 2019-07-28 17:51

I have wasted some time on this and thought someone else might find it useful:

When using the proto reflection API on map fields, you indeed treat the map field as a repeated field of com.google.protobuf.MapEntry:

FieldDescriptor mapFieldDescriptor = protoDescriptor.findFieldByName( map_field_name );
MapEntry.Builder entryBuilder = ( MapEntry.Builder ) topProtoBuilder.newBuilderForField( mapFieldDescriptor );

then for each entry in my map:

entryBuilder.setKey( e.getKey() );
entryBuilder.setValue( e.getValue() );
underlyingProtoBuilder.addRepeatedField( mapFieldDescriptor , entryBuilder.build() );

The only thing that still bothers me is the MapEntry doc saying: "Users shouldn't use this class" when I had to explicitly use the MapEntry.Builder.

Also I am not sure why protobuf doesn't let you simply builder.setField( mapFieldDescriptor , a java Map ) which seems much cleaner.

查看更多
登录 后发表回答