Skip to content

Commit 10cf878

Browse files
committed
enhancement(codecs): Use DescriptorPool from ProtobufDeserializer
1 parent 3e87de2 commit 10cf878

File tree

3 files changed

+44
-8
lines changed

3 files changed

+44
-8
lines changed

src/protobuf/descriptor.rs

+20-5
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,32 @@
11
use prost_reflect::{DescriptorPool, MessageDescriptor};
22
use std::path::Path;
33

4-
pub fn get_message_descriptor(
4+
pub fn get_message_pool_descriptor(
55
descriptor_set_path: &Path,
6-
message_type: &str,
7-
) -> std::result::Result<MessageDescriptor, String> {
6+
) -> std::result::Result<DescriptorPool, String> {
87
let b = std::fs::read(descriptor_set_path).map_err(|e| {
98
format!("Failed to open protobuf desc file '{descriptor_set_path:?}': {e}",)
109
})?;
11-
let pool = DescriptorPool::decode(b.as_slice()).map_err(|e| {
10+
DescriptorPool::decode(b.as_slice()).map_err(|e| {
1211
format!("Failed to parse protobuf desc file '{descriptor_set_path:?}': {e}")
13-
})?;
12+
})
13+
}
14+
15+
pub fn get_message_descriptor(
16+
descriptor_set_path: &Path,
17+
message_type: &str,
18+
) -> std::result::Result<MessageDescriptor, String> {
19+
let pool = get_message_pool_descriptor(descriptor_set_path)?;
1420
pool.get_message_by_name(message_type).ok_or_else(|| {
1521
format!("The message type '{message_type}' could not be found in '{descriptor_set_path:?}'")
1622
})
1723
}
24+
25+
pub fn get_message_descriptor_from_pool(
26+
pool: &DescriptorPool,
27+
message_type: &str,
28+
) -> std::result::Result<MessageDescriptor, String> {
29+
pool.get_message_by_name(message_type).ok_or_else(|| {
30+
format!("The message type '{message_type}' could not be found in the descriptor pool")
31+
})
32+
}

src/protobuf/mod.rs

+2
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ mod encode;
33
mod parse;
44

55
pub use descriptor::get_message_descriptor;
6+
pub use descriptor::get_message_pool_descriptor;
7+
pub use descriptor::get_message_descriptor_from_pool;
68

79
pub use encode::encode_message;
810
pub(crate) use encode::encode_proto;

src/protobuf/parse.rs

+22-3
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
use crate::compiler::prelude::*;
2+
use crate::protobuf::get_message_descriptor_from_pool;
23
use prost_reflect::ReflectMessage;
34
use prost_reflect::{DynamicMessage, MessageDescriptor};
45

56
pub fn proto_to_value(
7+
descriptor_pool: Option<&prost_reflect::DescriptorPool>,
68
prost_reflect_value: &prost_reflect::Value,
79
field_descriptor: Option<&prost_reflect::FieldDescriptor>,
810
) -> std::result::Result<Value, String> {
@@ -42,11 +44,27 @@ pub fn proto_to_value(
4244
}
4345
}
4446
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+
4563
let mut obj_map = ObjectMap::new();
4664
for field_desc in v.descriptor().fields() {
4765
if v.has_field(&field_desc) {
4866
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))?;
5068
obj_map.insert(field_desc.name().into(), out);
5169
}
5270
}
@@ -55,7 +73,7 @@ pub fn proto_to_value(
5573
prost_reflect::Value::List(v) => {
5674
let vec = v
5775
.iter()
58-
.map(|o| proto_to_value(o, field_descriptor))
76+
.map(|o| proto_to_value(descriptor_pool, o, field_descriptor))
5977
.collect::<Result<Vec<_>, String>>()?;
6078
Value::from(vec)
6179
}
@@ -80,7 +98,7 @@ pub fn proto_to_value(
8098
)
8199
})?
82100
.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()))?,
84102
))
85103
})
86104
.collect::<std::result::Result<ObjectMap, String>>()?,
@@ -99,6 +117,7 @@ pub(crate) fn parse_proto(descriptor: &MessageDescriptor, value: Value) -> Resol
99117
let dynamic_message = DynamicMessage::decode(descriptor.clone(), bytes)
100118
.map_err(|error| format!("Error parsing protobuf: {:?}", error))?;
101119
Ok(proto_to_value(
120+
None,
102121
&prost_reflect::Value::Message(dynamic_message),
103122
None,
104123
)?)

0 commit comments

Comments
 (0)