1
1
use crate :: compiler:: prelude:: * ;
2
+ use crate :: protobuf:: get_message_descriptor_from_pool;
2
3
use prost_reflect:: ReflectMessage ;
3
4
use prost_reflect:: { DynamicMessage , MessageDescriptor } ;
4
5
5
6
pub fn proto_to_value (
7
+ descriptor_pool : Option < & prost_reflect:: DescriptorPool > ,
6
8
prost_reflect_value : & prost_reflect:: Value ,
7
9
field_descriptor : Option < & prost_reflect:: FieldDescriptor > ,
8
10
) -> std:: result:: Result < Value , String > {
@@ -42,11 +44,27 @@ pub fn proto_to_value(
42
44
}
43
45
}
44
46
prost_reflect:: Value :: Message ( v) => {
47
+ if let Some ( descriptor_pool) = descriptor_pool {
48
+ if let Some ( type_url_cow) = v. get_field_by_name ( "type_url" ) {
49
+ if let Some ( value_cow) = v. get_field_by_name ( "value" ) {
50
+ if let prost_reflect:: Value :: String ( type_url) = & * type_url_cow {
51
+ if let prost_reflect:: Value :: Bytes ( value) = & * value_cow {
52
+ let type_name = type_url. trim_start_matches ( "type.googleapis.com/" ) ;
53
+ let message_descriptor = get_message_descriptor_from_pool ( descriptor_pool, type_name) ?;
54
+ let dynamic_message = DynamicMessage :: decode ( message_descriptor, value. clone ( ) )
55
+ . map_err ( |error| format ! ( "Error parsing embedded protobuf message: {:?}" , error) ) ?;
56
+ return proto_to_value ( Some ( descriptor_pool) , & prost_reflect:: Value :: Message ( dynamic_message) , None ) ;
57
+ }
58
+ }
59
+ }
60
+ }
61
+ }
62
+
45
63
let mut obj_map = ObjectMap :: new ( ) ;
46
64
for field_desc in v. descriptor ( ) . fields ( ) {
47
65
if v. has_field ( & field_desc) {
48
66
let field_value = v. get_field ( & field_desc) ;
49
- let out = proto_to_value ( field_value. as_ref ( ) , Some ( & field_desc) ) ?;
67
+ let out = proto_to_value ( descriptor_pool , field_value. as_ref ( ) , Some ( & field_desc) ) ?;
50
68
obj_map. insert ( field_desc. name ( ) . into ( ) , out) ;
51
69
}
52
70
}
@@ -55,7 +73,7 @@ pub fn proto_to_value(
55
73
prost_reflect:: Value :: List ( v) => {
56
74
let vec = v
57
75
. iter ( )
58
- . map ( |o| proto_to_value ( o, field_descriptor) )
76
+ . map ( |o| proto_to_value ( descriptor_pool , o, field_descriptor) )
59
77
. collect :: < Result < Vec < _ > , String > > ( ) ?;
60
78
Value :: from ( vec)
61
79
}
@@ -80,7 +98,7 @@ pub fn proto_to_value(
80
98
)
81
99
} ) ?
82
100
. into ( ) ,
83
- proto_to_value ( kv. 1 , Some ( & message_desc. map_entry_value_field ( ) ) ) ?,
101
+ proto_to_value ( descriptor_pool , kv. 1 , Some ( & message_desc. map_entry_value_field ( ) ) ) ?,
84
102
) )
85
103
} )
86
104
. collect :: < std:: result:: Result < ObjectMap , String > > ( ) ?,
@@ -99,6 +117,7 @@ pub(crate) fn parse_proto(descriptor: &MessageDescriptor, value: Value) -> Resol
99
117
let dynamic_message = DynamicMessage :: decode ( descriptor. clone ( ) , bytes)
100
118
. map_err ( |error| format ! ( "Error parsing protobuf: {:?}" , error) ) ?;
101
119
Ok ( proto_to_value (
120
+ None ,
102
121
& prost_reflect:: Value :: Message ( dynamic_message) ,
103
122
None ,
104
123
) ?)
0 commit comments