Filling up a map field in Proto using reflection API

被刻印的时光 ゝ 提交于 2019-12-11 02:31:21

问题


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:


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.



来源:https://stackoverflow.com/questions/43364297/filling-up-a-map-field-in-proto-using-reflection-api

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!