2015-01-27 45 views
0

我有我的協議緩衝區中定義的消息字段FieldDescriptor。我想開始爲該字段創建一個值,但是我試圖爲該FieldDescriptor獲取一個Message.Builder。我正在編寫的代碼非常通用 - 它被設計爲在MongoDB和Protocol Buffers之間進行序列化 - 所以我不能使用任何專用邏輯來處理當前正在使用的對象。Java中的Protobufs:你如何從FieldDescriptor獲得Message.Builder?

FieldDescriptor的JavaType是MESSAGE。它的MessageType稍好一些,因爲它包含消息的類型,但是類型在協議緩衝區命名空間中,所以我仍然不能使用反射來爲它獲取消息(至少不是乾淨地)。

我不知道還有什麼辦法。任何人都知道如何從FieldDescriptor構建Message.Builder?

+0

我做了將protobuf消息轉換爲sql和sql到proto的相同任務。 FieldDescriptor包含getMessageType()方法,它返回包含字段列表的Descriptors.Descriptor。從Descriptor構造Message.Builder有點棘手,當我來到辦公室時,我會展示解決方案 – ancalled 2015-01-27 01:54:59

+0

聽起來好像被喚醒會爲您提供答案;但您可以使用DynamicMessage(https://developers.google.com/protocol-buffers/docs/reference/java/com/google/protobuf/DynamicMessage),特別是DynamicMessage.newBuilder()和DynamicMessage.parseFrom()來處理協議動態緩衝消息。一個例子是https://gist.github.com/nandub/950285 – 2015-01-27 03:33:19

回答

4

如果您有包含類型的建設者的一個實例,你可以得到製造商的字段:

containingBuilder.getFieldBuilder(fieldDescriptor) 

,或者你可以得到一個新的建設者字段的類型的信息(但沒有具體現有實例的字段):

containingBuilder.newBuilderForField(fieldDescriptor) 

如果沒有包含類型的實例所有,但你知道包含類,你可以這樣做:

ContainingType.getDefaultInstanceForType() 
       .getField(fieldDescriptor) 
       .newBuilderForType() 

如果你甚至不知道包含的類(也許它甚至不是在你的罐子),並且你已經是一個描述符,那麼你可以使用DynamicMessage

DynamicMessage.newBuilder(fieldDescriptor) 

但是,請注意DynamicMessage只模擬真實類的反射界面;它實際上並不是實際類的實例(將由protoc生成)。而且,它比真實的課程慢很多。