use std::collections::HashMap;
use prost_types::field_descriptor_proto::Type;
use super::errors::{ParseError, ParseResult};
use super::registry::{DescriptorWithFieldCache, FieldInfo, MessageRegistry};
use super::types::{
convert_scalar_value, default_value_for_type, ComplexType, FieldValueRef, MapKeyRef,
PackedField, ParsedMapValue, MAP_ENTRY_KEY_FIELD_NUM, MAP_ENTRY_VALUE_FIELD_NUM,
MAX_NESTING_DEPTH,
};
use super::wire::{try_parse_field, WireValue};
#[derive(Debug)]
pub struct ParsedMessage<'a> {
scalars: Box<[Option<FieldValueRef<'a>>]>,
complex: Box<[ComplexType<'a>]>,
descriptor: &'a DescriptorWithFieldCache,
}
impl<'a> ParsedMessage<'a> {
#[inline(always)]
fn with_descriptor(descriptor: &'a DescriptorWithFieldCache) -> Self {
let scalars = vec![None; descriptor.scalar_count].into_boxed_slice();
let complex = (0..descriptor.complex_count)
.map(|_| ComplexType::Empty)
.collect::<Vec<_>>()
.into_boxed_slice();
Self {
scalars,
complex,
descriptor,
}
}
#[inline(always)]
pub fn has_field(&self, field_num: i32) -> bool {
let Some(field_info) = self.descriptor.get_field(field_num) else {
return false;
};
if field_info.is_scalar {
self.scalars[field_info.storage_index].is_some()
} else {
!matches!(self.complex[field_info.storage_index], ComplexType::Empty)
}
}
#[inline(always)]
pub fn get_field(&self, field_num: i32) -> Option<ParsedFieldValue<'_, 'a>> {
let field_info = self.descriptor.get_field(field_num)?;
Some(if field_info.is_scalar {
ParsedFieldValue::Scalar(self.scalars[field_info.storage_index]?)
} else {
ParsedFieldValue::Complex(&self.complex[field_info.storage_index])
})
}
#[inline(always)]
pub fn get_scalar(&self, field_num: i32) -> Option<&FieldValueRef<'a>> {
let field_info = self.descriptor.get_field(field_num)?;
self.scalars[field_info.storage_index].as_ref()
}
pub fn get_message(&self, field_num: i32) -> Option<&ParsedMessage<'a>> {
let field_info = self.descriptor.get_field(field_num)?;
match &self.complex[field_info.storage_index] {
ComplexType::Message(m) => Some(m),
_ => None,
}
}
#[inline(always)]
pub fn get_repeated_scalars(&self, field_num: i32) -> &[FieldValueRef<'a>] {
self.descriptor
.get_field(field_num)
.and_then(|f| match &self.complex[f.storage_index] {
ComplexType::RepeatedScalar(v) => Some(v.as_slice()),
_ => None,
})
.unwrap_or(&[])
}
pub fn get_repeated_messages(&self, field_num: i32) -> &[ParsedMessage<'a>] {
self.descriptor
.get_field(field_num)
.and_then(|f| match &self.complex[f.storage_index] {
ComplexType::RepeatedMessage(v) => Some(v.as_slice()),
_ => None,
})
.unwrap_or(&[])
}
pub fn get_map_entries(
&self,
field_num: i32,
) -> impl Iterator<Item = (&MapKeyRef<'a>, &ParsedMapValue<'a>)> {
self.descriptor
.get_field(field_num)
.and_then(|f| match &self.complex[f.storage_index] {
ComplexType::Map(m) => Some(m),
_ => None,
})
.into_iter()
.flat_map(|m| m.iter())
}
pub fn get_map_entries_count(&self, field_num: i32) -> usize {
self.descriptor
.get_field(field_num)
.and_then(|f| match &self.complex[f.storage_index] {
ComplexType::Map(m) => Some(m.len()),
_ => None,
})
.unwrap_or(0)
}
#[inline(always)]
fn set_scalar(&mut self, field_info: &FieldInfo, value: FieldValueRef<'a>) {
self.scalars[field_info.storage_index] = Some(value);
}
#[inline(always)]
fn merge_or_set_message(&mut self, field_info: &FieldInfo, value: ParsedMessage<'a>) {
let slot = &mut self.complex[field_info.storage_index];
if let ComplexType::Message(existing) = slot {
existing.merge_from(value);
} else {
*slot = ComplexType::Message(value);
}
}
#[inline(always)]
fn merge_from(&mut self, other: ParsedMessage<'a>) {
debug_assert!(
std::ptr::eq(self.descriptor, other.descriptor),
"merge_from requires both messages to share a descriptor"
);
for group in self.descriptor.oneof_groups() {
let active = group.iter().find(|m| {
if m.is_scalar {
other.scalars[m.storage_index].is_some()
} else {
!matches!(other.complex[m.storage_index], ComplexType::Empty)
}
});
if let Some(active) = active {
for m in group {
if m.is_scalar == active.is_scalar && m.storage_index == active.storage_index {
continue;
}
if m.is_scalar {
self.scalars[m.storage_index] = None;
} else {
self.complex[m.storage_index] = ComplexType::Empty;
}
}
}
}
let other_scalars = Vec::from(other.scalars);
for (slot, value) in self.scalars.iter_mut().zip(other_scalars) {
if value.is_some() {
*slot = value;
}
}
let other_complex = Vec::from(other.complex);
for (slot, value) in self.complex.iter_mut().zip(other_complex) {
match value {
ComplexType::Empty => {}
ComplexType::Message(om) => {
if let ComplexType::Message(sm) = slot {
sm.merge_from(om);
} else {
*slot = ComplexType::Message(om);
}
}
ComplexType::RepeatedScalar(ov) => {
if let ComplexType::RepeatedScalar(sv) = slot {
sv.extend(ov);
} else {
*slot = ComplexType::RepeatedScalar(ov);
}
}
ComplexType::RepeatedMessage(ov) => {
if let ComplexType::RepeatedMessage(sv) = slot {
sv.extend(ov);
} else {
*slot = ComplexType::RepeatedMessage(ov);
}
}
ComplexType::Map(om) => {
if let ComplexType::Map(sm) = slot {
sm.extend(om);
} else {
*slot = ComplexType::Map(om);
}
}
}
}
}
#[inline(always)]
fn add_repeated_scalar(
&mut self,
field_info: &FieldInfo,
field_num: i32,
value: FieldValueRef<'a>,
) -> ParseResult<()> {
let complex_type = &mut self.complex[field_info.storage_index];
match complex_type {
ComplexType::RepeatedScalar(vec) => vec.push(value),
ComplexType::Empty => *complex_type = ComplexType::RepeatedScalar(vec![value]),
_ => {
return Err(ParseError::ComplexTypeMismatch {
expected: "RepeatedScalar",
actual: complex_type.as_str(),
field_num,
});
}
}
Ok(())
}
fn add_repeated_message(
&mut self,
field_info: &FieldInfo,
field_num: i32,
value: ParsedMessage<'a>,
) -> ParseResult<()> {
let complex_type = &mut self.complex[field_info.storage_index];
match complex_type {
ComplexType::RepeatedMessage(vec) => vec.push(value),
ComplexType::Empty => *complex_type = ComplexType::RepeatedMessage(vec![value]),
_ => {
return Err(ParseError::ComplexTypeMismatch {
expected: "RepeatedMessage",
actual: complex_type.as_str(),
field_num,
});
}
}
Ok(())
}
fn add_map_entry(
&mut self,
field_info: &FieldInfo,
field_num: i32,
key: MapKeyRef<'a>,
value: ParsedMapValue<'a>,
) -> ParseResult<()> {
let complex_type = &mut self.complex[field_info.storage_index];
match complex_type {
ComplexType::Map(map) => {
map.insert(key, value);
}
ComplexType::Empty => {
let mut map = HashMap::new();
map.insert(key, value);
*complex_type = ComplexType::Map(map);
}
_ => {
return Err(ParseError::ComplexTypeMismatch {
expected: "Map",
actual: complex_type.as_str(),
field_num,
});
}
}
Ok(())
}
#[cold]
fn clear_oneof_siblings(&mut self, oneof_index: i32, field_info: &FieldInfo) {
for member in self.descriptor.get_oneof_group(oneof_index) {
if member.is_scalar == field_info.is_scalar
&& member.storage_index == field_info.storage_index
{
continue;
}
if member.is_scalar {
self.scalars[member.storage_index] = None;
} else {
self.complex[member.storage_index] = ComplexType::Empty;
}
}
}
#[inline(always)]
pub fn parse(bytes: &'a [u8], registry: &'a MessageRegistry) -> ParseResult<ParsedMessage<'a>> {
Self::parse_internal(
bytes, None,
registry, 0,
)
}
#[inline(always)]
fn parse_internal(
bytes: &'a [u8],
type_name: Option<&str>,
registry: &'a MessageRegistry,
depth: usize,
) -> ParseResult<ParsedMessage<'a>> {
if depth > MAX_NESTING_DEPTH {
return Err(ParseError::MaxNestingDepthExceeded {
max: MAX_NESTING_DEPTH,
});
}
let descriptor = match type_name {
Some(name) => registry
.get(name)
.ok_or_else(|| ParseError::UnknownTypeName {
type_name: name.to_string(),
})?,
None => ®istry.root_descriptor,
};
let mut result = ParsedMessage::with_descriptor(descriptor);
let mut remaining = bytes;
while !remaining.is_empty() {
let (parsed_field, rest) = try_parse_field(remaining)?;
remaining = rest;
let field_num = parsed_field.field_num;
let Some(field_info) = descriptor.get_field(field_num) else {
continue;
};
if field_info.is_scalar {
let value = convert_scalar_value(
field_info.field_type,
&parsed_field.value,
parsed_field.field_num,
)?;
if let Some(idx) = field_info.oneof_index {
result.clear_oneof_siblings(idx, field_info);
}
result.set_scalar(field_info, value);
continue;
}
if field_info.field_type == Type::Message {
let nested_bytes = parsed_field.value.try_as_bytes(parsed_field.field_num)?;
let nested_type_name = field_info.type_name.as_deref().unwrap_or("");
if let Some(nested_desc) = registry.get(nested_type_name) {
if nested_desc.is_map_entry {
let (key, value) = ParsedMessage::parse_map_entry_recursive(
nested_bytes,
nested_desc,
registry,
depth + 1,
)?;
result.add_map_entry(field_info, field_num, key, value)?;
continue;
}
}
let nested = ParsedMessage::parse_internal(
nested_bytes,
Some(nested_type_name),
registry,
depth + 1,
)?;
if field_info.is_repeated {
result.add_repeated_message(field_info, field_num, nested)?;
} else {
if let Some(idx) = field_info.oneof_index {
result.clear_oneof_siblings(idx, field_info);
}
result.merge_or_set_message(field_info, nested);
}
} else {
let is_packed = PackedField::is_packable_type(field_info.field_type)
&& matches!(parsed_field.value, WireValue::Len(_));
if is_packed {
let bytes = parsed_field.value.try_as_bytes(parsed_field.field_num)?;
let packed = PackedField::from_bytes(
bytes,
field_info.field_type,
parsed_field.field_num,
)?;
let complex_type = &mut result.complex[field_info.storage_index];
if matches!(complex_type, ComplexType::Empty) {
*complex_type = ComplexType::RepeatedScalar(Vec::new());
}
let values_vec = match complex_type {
ComplexType::RepeatedScalar(vec) => vec,
_ => {
return Err(ParseError::ComplexTypeMismatch {
expected: "RepeatedScalar",
actual: complex_type.as_str(),
field_num: parsed_field.field_num,
});
}
};
packed.expand_into(
field_info.field_type,
values_vec,
parsed_field.field_num,
)?;
} else {
let value = convert_scalar_value(
field_info.field_type,
&parsed_field.value,
parsed_field.field_num,
)?;
result.add_repeated_scalar(field_info, parsed_field.field_num, value)?;
}
}
}
Ok(result)
}
fn parse_map_entry_recursive(
bytes: &'a [u8],
descriptor: &'a DescriptorWithFieldCache,
registry: &'a MessageRegistry,
depth: usize,
) -> ParseResult<(MapKeyRef<'a>, ParsedMapValue<'a>)> {
let mut key: Option<FieldValueRef<'a>> = None;
let mut value: Option<ParsedMapValue<'a>> = None;
let mut remaining = bytes;
let key_info = descriptor.get_field(MAP_ENTRY_KEY_FIELD_NUM);
let value_info = descriptor.get_field(MAP_ENTRY_VALUE_FIELD_NUM);
while !remaining.is_empty() {
let (parsed_field, rest) = try_parse_field(remaining)?;
remaining = rest;
let field_num = parsed_field.field_num;
if let Some(field_info) = descriptor.get_field(field_num) {
match field_num {
MAP_ENTRY_KEY_FIELD_NUM => {
let k = convert_scalar_value(
field_info.field_type,
&parsed_field.value,
MAP_ENTRY_KEY_FIELD_NUM,
)?;
key = Some(k);
}
MAP_ENTRY_VALUE_FIELD_NUM => {
if field_info.field_type == Type::Message {
let nested_bytes =
parsed_field.value.try_as_bytes(parsed_field.field_num)?;
let new_value = Self::parse_map_message_value(
field_info.type_name.as_deref().unwrap_or(""),
nested_bytes,
registry,
depth,
)?;
match (value.as_mut(), new_value) {
(
Some(ParsedMapValue::Message(existing)),
ParsedMapValue::Message(new_msg),
) => existing.merge_from(new_msg),
(_, new_value) => value = Some(new_value),
}
} else {
let v = convert_scalar_value(
field_info.field_type,
&parsed_field.value,
MAP_ENTRY_VALUE_FIELD_NUM,
)?;
value = Some(ParsedMapValue::Scalar(v));
}
}
_ => {}
}
}
}
let key_type = key_info.map(|f| f.field_type).unwrap_or(Type::Bytes);
let value_type = value_info.map(|f| f.field_type).unwrap_or(Type::Bytes);
let key_field_value = key.unwrap_or_else(|| default_value_for_type(key_type));
let value = match value {
Some(v) => v,
None if value_type == Type::Message => {
let type_name = value_info
.and_then(|f| f.type_name.as_deref())
.unwrap_or_default();
Self::parse_map_message_value(type_name, &[], registry, depth)?
}
None => ParsedMapValue::Scalar(default_value_for_type(value_type)),
};
let map_key =
MapKeyRef::from_field_value(key_field_value).ok_or(ParseError::InvalidMapKeyType {
field_num: MAP_ENTRY_KEY_FIELD_NUM,
})?;
Ok((map_key, value))
}
fn parse_map_message_value(
type_name: &str,
bytes: &'a [u8],
registry: &'a MessageRegistry,
depth: usize,
) -> ParseResult<ParsedMapValue<'a>> {
let nested = ParsedMessage::parse_internal(bytes, Some(type_name), registry, depth)?;
Ok(ParsedMapValue::Message(nested))
}
}
#[derive(Debug)]
pub enum ParsedFieldValue<'s, 'a> {
Scalar(FieldValueRef<'a>),
Complex(&'s ComplexType<'a>),
}
impl<'a, 'b> std::ops::Deref for ParsedFieldValue<'a, 'b> {
type Target = Self;
fn deref(&self) -> &Self::Target {
self
}
}
#[cfg(test)]
pub mod tests {
use prost_types::field_descriptor_proto::Type;
use prost_types::{
DescriptorProto, FieldDescriptorProto, MessageOptions, OneofDescriptorProto,
};
use super::*;
use crate::zeroparser::sparse_field_map::MAX_INLINE_CAPACITY;
const LABEL_OPTIONAL: i32 = 1;
const LABEL_REPEATED: i32 = 3;
pub fn make_field(
number: i32,
name: &str,
field_type: Type,
repeated: bool,
type_name: Option<&str>,
) -> FieldDescriptorProto {
FieldDescriptorProto {
name: Some(name.to_string()),
number: Some(number),
label: Some(if repeated {
LABEL_REPEATED
} else {
LABEL_OPTIONAL
}),
r#type: Some(field_type as i32),
type_name: type_name.map(|s| s.to_string()),
extendee: None,
default_value: None,
oneof_index: None,
json_name: None,
options: None,
proto3_optional: None,
}
}
pub fn make_descriptor(name: &str, fields: Vec<FieldDescriptorProto>) -> DescriptorProto {
DescriptorProto {
name: Some(name.to_string()),
field: fields,
extension: vec![],
nested_type: vec![],
enum_type: vec![],
extension_range: vec![],
oneof_decl: vec![],
options: None,
reserved_range: vec![],
reserved_name: vec![],
}
}
fn make_map_entry_descriptor(name: &str, key_type: Type, value_type: Type) -> DescriptorProto {
let mut desc = make_descriptor(
name,
vec![
make_field(1, "key", key_type, false, None),
make_field(2, "value", value_type, false, None),
],
);
desc.options = Some(MessageOptions {
map_entry: Some(true),
..Default::default()
});
desc
}
fn assert_scalar(parsed: &ParsedMessage, expected: FieldValueRef, field_num: i32) {
let actual = parsed
.get_scalar(field_num)
.unwrap_or_else(|| panic!("Field {} not found", field_num));
assert_eq!(*actual, expected, "Field {} mismatch", field_num);
}
fn ld(field: u8, payload: &[u8]) -> Vec<u8> {
assert!(payload.len() < 128, "ld helper assumes single-byte length");
let mut v = Vec::with_capacity(payload.len() + 2);
v.push(field << 3 | 2);
v.push(payload.len() as u8);
v.extend_from_slice(payload);
v
}
#[test]
fn parse_scalar_fields() {
let cases: Vec<(i32, &str, Type, &[u8], FieldValueRef)> = vec![
(
1,
"id",
Type::Int32,
&[8, 0x96, 0x01],
FieldValueRef::Int32(150),
),
(
1,
"big",
Type::Int64,
&[8, 0xAC, 0x02],
FieldValueRef::Int64(300),
),
(
1,
"count",
Type::Uint32,
&[8, 42],
FieldValueRef::UInt32(42),
),
(
1,
"ts",
Type::Uint64,
&[8, 0xE8, 0x07],
FieldValueRef::UInt64(1000),
),
(1, "delta", Type::Sint32, &[8, 1], FieldValueRef::Int32(-1)),
(1, "offset", Type::Sint64, &[8, 3], FieldValueRef::Int64(-2)),
(1, "flag", Type::Bool, &[8, 1], FieldValueRef::Bool(true)),
(1, "flag", Type::Bool, &[8, 0], FieldValueRef::Bool(false)),
(
1,
"f32",
Type::Fixed32,
&[13, 0x78, 0x56, 0x34, 0x12],
FieldValueRef::UInt32(0x12345678),
),
(
1,
"f64",
Type::Fixed64,
&[9, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01],
FieldValueRef::UInt64(0x0102030405060708),
),
(
1,
"sf32",
Type::Sfixed32,
&[13, 0xFF, 0xFF, 0xFF, 0xFF],
FieldValueRef::Int32(-1),
),
(
1,
"sf64",
Type::Sfixed64,
&[9, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF],
FieldValueRef::Int64(-1),
),
(
1,
"name",
Type::String,
&[10, 5, b'h', b'e', b'l', b'l', b'o'],
FieldValueRef::String("hello"),
),
(
1,
"data",
Type::Bytes,
&[10, 3, 0xDE, 0xAD, 0xBE],
FieldValueRef::Bytes(&[0xDE, 0xAD, 0xBE]),
),
];
for (field_num, field_name, field_type, wire_bytes, expected_value) in cases {
let desc = make_descriptor(
"Test",
vec![make_field(field_num, field_name, field_type, false, None)],
);
let registry = MessageRegistry::from_descriptor(&desc);
let parsed = ParsedMessage::parse(wire_bytes, ®istry).expect("parse failed");
assert_scalar(&parsed, expected_value, field_num);
}
}
#[test]
fn parse_float_double() {
let float_bits = std::f32::consts::PI.to_bits().to_le_bytes();
let float_bytes = [&[13u8][..], &float_bits[..]].concat();
let desc = make_descriptor("Test", vec![make_field(1, "val", Type::Float, false, None)]);
let registry = MessageRegistry::from_descriptor(&desc);
let parsed = ParsedMessage::parse(&float_bytes, ®istry).unwrap();
match parsed.get_scalar(1) {
Some(&FieldValueRef::Float(f)) => assert!((f - std::f32::consts::PI).abs() < 0.001),
other => panic!("Expected Float, got {:?}", other),
}
let double_bits = std::f64::consts::E.to_bits().to_le_bytes();
let double_bytes = [&[9u8][..], &double_bits[..]].concat();
let desc = make_descriptor(
"Test",
vec![make_field(1, "val", Type::Double, false, None)],
);
let registry = MessageRegistry::from_descriptor(&desc);
let parsed = ParsedMessage::parse(&double_bytes, ®istry).unwrap();
match parsed.get_scalar(1) {
Some(&FieldValueRef::Double(d)) => assert!((d - std::f64::consts::E).abs() < 0.00001),
other => panic!("Expected Double, got {:?}", other),
}
}
#[test]
fn parse_empty_message() {
let desc = make_descriptor("Empty", vec![make_field(1, "id", Type::Int32, false, None)]);
let registry = MessageRegistry::from_descriptor(&desc);
let parsed = ParsedMessage::parse(&[], ®istry).unwrap();
assert!(!parsed.has_field(1));
assert!(!parsed.has_field(-1));
assert!(!parsed.has_field(i32::MIN));
assert_eq!(parsed.get_scalar(-1), None);
assert_eq!(parsed.get_scalar(i32::MIN), None);
}
#[test]
fn parse_multiple_fields() {
let desc = make_descriptor(
"Multi",
vec![
make_field(1, "id", Type::Int32, false, None),
make_field(2, "name", Type::String, false, None),
],
);
let registry = MessageRegistry::from_descriptor(&desc);
let wire = &[8, 42, 18, 2, b'h', b'i'];
let parsed = ParsedMessage::parse(wire, ®istry).unwrap();
assert_scalar(&parsed, FieldValueRef::Int32(42), 1 );
assert_scalar(&parsed, FieldValueRef::String("hi"), 2 );
}
#[test]
fn parse_repeated_scalars() {
let desc = make_descriptor("Test", vec![make_field(1, "nums", Type::Int32, true, None)]);
let registry = MessageRegistry::from_descriptor(&desc);
let wire = &[8, 1, 8, 2, 8, 3];
let parsed = ParsedMessage::parse(wire, ®istry).unwrap();
let values = parsed.get_repeated_scalars(1);
assert_eq!(values.len(), 3);
assert_eq!(values[0], FieldValueRef::Int32(1));
assert_eq!(values[1], FieldValueRef::Int32(2));
assert_eq!(values[2], FieldValueRef::Int32(3));
}
#[test]
fn parse_packed_and_mixed_repeated() {
let cases: Vec<(&str, Type, &[u8], Vec<FieldValueRef>)> = vec![
(
"int32_packed",
Type::Int32,
&[10, 3, 1, 2, 127],
vec![
FieldValueRef::Int32(1),
FieldValueRef::Int32(2),
FieldValueRef::Int32(127),
],
),
(
"fixed32_packed",
Type::Fixed32,
&[10, 8, 1, 0, 0, 0, 2, 0, 0, 0],
vec![FieldValueRef::UInt32(1), FieldValueRef::UInt32(2)],
),
(
"fixed64_packed",
Type::Fixed64,
&[10, 16, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0],
vec![FieldValueRef::UInt64(1), FieldValueRef::UInt64(2)],
),
("int32_empty", Type::Int32, &[10, 0], vec![]),
("fixed32_empty", Type::Fixed32, &[10, 0], vec![]),
("fixed64_empty", Type::Fixed64, &[10, 0], vec![]),
(
"int32_mixed",
Type::Int32,
&[8, 1, 10, 2, 2, 3, 8, 4],
vec![
FieldValueRef::Int32(1),
FieldValueRef::Int32(2),
FieldValueRef::Int32(3),
FieldValueRef::Int32(4),
],
),
(
"int32_multi_packed",
Type::Int32,
&[10, 2, 1, 2, 10, 2, 3, 4],
vec![
FieldValueRef::Int32(1),
FieldValueRef::Int32(2),
FieldValueRef::Int32(3),
FieldValueRef::Int32(4),
],
),
(
"uint32_mixed",
Type::Uint32,
&[8, 10, 10, 2, 20, 30, 8, 40],
vec![
FieldValueRef::UInt32(10),
FieldValueRef::UInt32(20),
FieldValueRef::UInt32(30),
FieldValueRef::UInt32(40),
],
),
(
"bool_mixed",
Type::Bool,
&[8, 1, 10, 2, 0, 1, 8, 0],
vec![
FieldValueRef::Bool(true),
FieldValueRef::Bool(false),
FieldValueRef::Bool(true),
FieldValueRef::Bool(false),
],
),
(
"fixed32_mixed",
Type::Fixed32,
&[
13, 1, 0, 0, 0, 10, 8, 2, 0, 0, 0, 3, 0, 0, 0, 13, 4, 0, 0, 0, ],
vec![
FieldValueRef::UInt32(1),
FieldValueRef::UInt32(2),
FieldValueRef::UInt32(3),
FieldValueRef::UInt32(4),
],
),
];
for (name, field_type, wire_bytes, expected_values) in cases {
let desc = make_descriptor("Test", vec![make_field(1, "arr", field_type, true, None)]);
let registry = MessageRegistry::from_descriptor(&desc);
let parsed = ParsedMessage::parse(wire_bytes, ®istry)
.unwrap_or_else(|_| panic!("{}: parse failed", name));
let values = parsed.get_repeated_scalars(1);
assert_eq!(
values.len(),
expected_values.len(),
"{}: length mismatch",
name
);
for (i, expected_val) in expected_values.iter().enumerate() {
assert_eq!(values[i], *expected_val, "{}: value {} mismatch", name, i);
}
}
}
#[test]
fn parse_nested_struct_recursive() {
let inner = make_descriptor(
"Inner",
vec![
make_field(1, "a", Type::Int32, false, None),
make_field(2, "b", Type::String, false, None),
],
);
let mut outer = make_descriptor(
"Outer",
vec![make_field(
1,
"inner",
Type::Message,
false,
Some(".Outer.Inner"),
)],
);
outer.nested_type.push(inner);
let registry = MessageRegistry::from_descriptor(&outer);
let inner_wire: &[u8] = &[8, 42, 18, 5, b'h', b'e', b'l', b'l', b'o'];
let mut wire = vec![10, inner_wire.len() as u8];
wire.extend_from_slice(inner_wire);
let parsed = ParsedMessage::parse(&wire, ®istry).unwrap();
let inner_parsed = parsed.get_message(1).expect("inner should be parsed");
assert_eq!(inner_parsed.get_scalar(1), Some(&FieldValueRef::Int32(42)));
assert_eq!(
inner_parsed.get_scalar(2),
Some(&FieldValueRef::String("hello"))
);
}
#[test]
fn parse_repeated_messages() {
let item = make_descriptor("Item", vec![make_field(1, "id", Type::Int32, false, None)]);
let mut container = make_descriptor(
"Container",
vec![make_field(
1,
"items",
Type::Message,
true,
Some(".Container.Item"),
)],
);
container.nested_type.push(item);
let registry = MessageRegistry::from_descriptor(&container);
let wire = &[10, 2, 8, 1, 10, 2, 8, 2];
let parsed = ParsedMessage::parse(wire, ®istry).unwrap();
let items = parsed.get_repeated_messages(1);
assert_eq!(items.len(), 2);
assert_eq!(items[0].get_scalar(1), Some(&FieldValueRef::Int32(1)));
assert_eq!(items[1].get_scalar(1), Some(&FieldValueRef::Int32(2)));
}
#[test]
fn parse_map_scalar_values() {
let map_entry = make_map_entry_descriptor("MapEntry", Type::String, Type::Int32);
let mut outer = make_descriptor(
"Outer",
vec![make_field(
1,
"items",
Type::Message,
true,
Some(".Outer.MapEntry"),
)],
);
outer.nested_type.push(map_entry);
let registry = MessageRegistry::from_descriptor(&outer);
let wire = &[10, 7, 10, 3, b'f', b'o', b'o', 16, 42];
let parsed = ParsedMessage::parse(wire, ®istry).unwrap();
assert_eq!(parsed.get_map_entries_count(1), 1);
let entries: Vec<_> = parsed.get_map_entries(1).collect();
assert_eq!(*entries[0].0, MapKeyRef::String("foo"));
match entries[0].1 {
ParsedMapValue::Scalar(v) => assert_eq!(v, &FieldValueRef::Int32(42)),
_ => panic!("Expected scalar value"),
}
let int_key_map_entry = make_map_entry_descriptor("IntKeyMap", Type::Int32, Type::String);
let mut outer2 = make_descriptor(
"Outer2",
vec![make_field(
1,
"items",
Type::Message,
true,
Some(".Outer2.IntKeyMap"),
)],
);
outer2.nested_type.push(int_key_map_entry);
let registry2 = MessageRegistry::from_descriptor(&outer2);
let wire2 = &[10, 6, 8, 42, 18, 2, b'h', b'i'];
let parsed2 = ParsedMessage::parse(wire2, ®istry2).unwrap();
assert_eq!(parsed2.get_map_entries_count(1), 1);
let entries2: Vec<_> = parsed2.get_map_entries(1).collect();
assert_eq!(*entries2[0].0, MapKeyRef::Int32(42));
match entries2[0].1 {
ParsedMapValue::Scalar(v) => assert_eq!(v, &FieldValueRef::String("hi")),
_ => panic!("Expected scalar value"),
}
}
#[test]
fn parse_map_message_values() {
let value_msg = make_descriptor(
"ValueMsg",
vec![make_field(1, "x", Type::Int32, false, None)],
);
let mut map_entry = make_descriptor(
"MapEntry",
vec![
make_field(1, "key", Type::String, false, None),
make_field(2, "value", Type::Message, false, Some(".Outer.ValueMsg")),
],
);
map_entry.options = Some(MessageOptions {
map_entry: Some(true),
..Default::default()
});
let mut outer = make_descriptor(
"Outer",
vec![make_field(
1,
"items",
Type::Message,
true,
Some(".Outer.MapEntry"),
)],
);
outer.nested_type.push(map_entry);
outer.nested_type.push(value_msg);
let registry = MessageRegistry::from_descriptor(&outer);
let wire = &[10, 7, 10, 1, b'k', 18, 2, 8, 99];
let parsed = ParsedMessage::parse(wire, ®istry).unwrap();
assert_eq!(parsed.get_map_entries_count(1), 1);
let entries: Vec<_> = parsed.get_map_entries(1).collect();
assert_eq!(*entries[0].0, MapKeyRef::String("k"));
match entries[0].1 {
ParsedMapValue::Message(m) => {
assert_eq!(m.get_scalar(1), Some(&FieldValueRef::Int32(99)))
}
_ => panic!("Expected message value"),
}
let wire_missing_value = &[10, 3, 10, 1, b'k'];
let parsed = ParsedMessage::parse(wire_missing_value, ®istry).unwrap();
assert_eq!(parsed.get_map_entries_count(1), 1);
let entries: Vec<_> = parsed.get_map_entries(1).collect();
assert_eq!(*entries[0].0, MapKeyRef::String("k"));
match entries[0].1 {
ParsedMapValue::Message(m) => assert_eq!(m.get_scalar(1), None),
other => panic!("Expected empty message value, got {:?}", other),
}
let wire_empty_entry = &[10, 0];
let parsed = ParsedMessage::parse(wire_empty_entry, ®istry).unwrap();
assert_eq!(parsed.get_map_entries_count(1), 1);
let entries: Vec<_> = parsed.get_map_entries(1).collect();
assert_eq!(*entries[0].0, MapKeyRef::String(""));
match entries[0].1 {
ParsedMapValue::Message(m) => assert_eq!(m.get_scalar(1), None),
other => panic!("Expected empty message value, got {:?}", other),
}
}
#[test]
fn parse_map_with_defaults() {
let cases: Vec<(&str, &[u8], MapKeyRef, FieldValueRef)> = vec![
(
"both",
&[10, 3, b'k', b'e', b'y', 16, 5],
MapKeyRef::String("key"),
FieldValueRef::Int32(5),
),
(
"no_value",
&[10, 1, b'x'],
MapKeyRef::String("x"),
FieldValueRef::Int32(0),
),
(
"no_key",
&[16, 99],
MapKeyRef::String(""),
FieldValueRef::Int32(99),
),
("empty", &[], MapKeyRef::String(""), FieldValueRef::Int32(0)),
];
let map_entry = make_map_entry_descriptor("MapEntry", Type::String, Type::Int32);
let mut outer = make_descriptor(
"Outer",
vec![make_field(
1,
"m",
Type::Message,
true,
Some(".Outer.MapEntry"),
)],
);
outer.nested_type.push(map_entry);
let registry = MessageRegistry::from_descriptor(&outer);
for (case_name, entry_wire, expected_key, expected_value) in cases {
let mut wire = vec![10, entry_wire.len() as u8];
wire.extend_from_slice(entry_wire);
let parsed = ParsedMessage::parse(&wire, ®istry).expect(case_name);
assert_eq!(parsed.get_map_entries_count(1), 1, "case: {}", case_name);
let entries: Vec<_> = parsed.get_map_entries(1).collect();
assert_eq!(*entries[0].0, expected_key, "case: {} key", case_name);
match entries[0].1 {
ParsedMapValue::Scalar(v) => {
assert_eq!(v, &expected_value, "case: {} value", case_name)
}
_ => panic!("Expected scalar for case {}", case_name),
}
}
}
#[test]
fn parse_errors() {
let cases: Vec<(&str, Vec<FieldDescriptorProto>, &[u8], ParseError)> = vec![
(
"invalid_utf8",
vec![make_field(1, "name", Type::String, false, None)],
&[10, 2, 0xFF, 0xFE],
ParseError::InvalidUtf8 { field_num: 1 },
),
(
"buffer_too_short",
vec![make_field(1, "f", Type::Fixed32, false, None)],
&[13, 0x01, 0x02],
ParseError::BufferTooShort {
needed: 4,
available: 2,
field_num: 1,
},
),
(
"invalid_wire_type",
vec![make_field(1, "x", Type::Int32, false, None)],
&[14],
ParseError::InvalidWireType(6),
),
(
"truncated_varint",
vec![make_field(1, "x", Type::Int32, false, None)],
&[8, 0x80],
ParseError::TruncatedVarint,
),
];
for (case_name, fields, wire_bytes, expected_error) in cases {
let desc = make_descriptor("Test", fields);
let registry = MessageRegistry::from_descriptor(&desc);
let result = ParsedMessage::parse(wire_bytes, ®istry);
assert!(result.is_err(), "case {} should fail", case_name);
assert_eq!(result.unwrap_err(), expected_error, "case: {}", case_name);
}
}
#[test]
fn parse_unknown_type_returns_error() {
let desc = make_descriptor("Test", vec![make_field(1, "id", Type::Int32, false, None)]);
let registry = MessageRegistry::from_descriptor(&desc);
let result = ParsedMessage::parse_internal(&[8, 42], Some(".Unknown"), ®istry, 0);
assert!(matches!(
result,
Err(ParseError::UnknownTypeName { type_name }) if type_name == ".Unknown"
));
}
#[test]
fn parse_max_nesting_depth_exceeded() {
let desc = make_descriptor("Test", vec![make_field(1, "id", Type::Int32, false, None)]);
let registry = MessageRegistry::from_descriptor(&desc);
let result = ParsedMessage::parse_internal(
&[8, 42],
Some(".Test"),
®istry,
MAX_NESTING_DEPTH + 1,
);
assert!(matches!(
result,
Err(ParseError::MaxNestingDepthExceeded { max })
if max == MAX_NESTING_DEPTH
));
}
#[test]
fn parse_last_occurrence_wins() {
let desc = make_descriptor(
"Test",
vec![
make_field(1, "id", Type::Int32, false, None),
make_field(2, "name", Type::String, false, None),
],
);
let registry = MessageRegistry::from_descriptor(&desc);
let wire = &[
8, 10, 18, 5, b'f', b'i', b'r', b's', b't', 8, 20, 8, 30, 18, 6, b's', b'e', b'c',
b'o', b'n', b'd',
];
let parsed = ParsedMessage::parse(wire, ®istry).unwrap();
assert_eq!(parsed.get_scalar(1), Some(&FieldValueRef::Int32(30)));
assert_eq!(parsed.get_scalar(2), Some(&FieldValueRef::String("second")));
}
#[test]
fn parse_deeply_nested() {
let level2 = make_descriptor("L2", vec![make_field(1, "val", Type::Int32, false, None)]);
let mut level1 = make_descriptor(
"L1",
vec![make_field(
1,
"l2",
Type::Message,
false,
Some(".Root.L1.L2"),
)],
);
level1.nested_type.push(level2);
let mut root = make_descriptor(
"Root",
vec![make_field(1, "l1", Type::Message, false, Some(".Root.L1"))],
);
root.nested_type.push(level1);
let registry = MessageRegistry::from_descriptor(&root);
let wire = &[10, 4, 10, 2, 8, 42];
let parsed = ParsedMessage::parse(wire, ®istry).unwrap();
let l1 = parsed.get_message(1).expect("l1");
let l2 = l1.get_message(1).expect("l2");
assert_eq!(l2.get_scalar(1), Some(&FieldValueRef::Int32(42)));
}
#[test]
fn field_presence_all_scalar_types() {
let desc = make_descriptor(
"Test",
vec![
make_field(1, "int32_field", Type::Int32, false, None),
make_field(2, "int64_field", Type::Int64, false, None),
make_field(3, "uint32_field", Type::Uint32, false, None),
make_field(4, "uint64_field", Type::Uint64, false, None),
make_field(5, "bool_field", Type::Bool, false, None),
make_field(6, "float_field", Type::Float, false, None),
make_field(7, "double_field", Type::Double, false, None),
make_field(8, "string_field", Type::String, false, None),
make_field(9, "bytes_field", Type::Bytes, false, None),
],
);
let registry = MessageRegistry::from_descriptor(&desc);
let wire = &[
8, 0, 16, 0, 24, 0, 32, 0, 40, 0, 53, 0, 0, 0, 0, 57, 0, 0, 0, 0, 0, 0, 0, 0, 66, 0, 74, 0, ];
let parsed = ParsedMessage::parse(wire, ®istry).unwrap();
for field_num in 1..=9 {
assert!(
parsed.has_field(field_num),
"Field {} should be present",
field_num
);
}
let parsed_empty = ParsedMessage::parse(&[], ®istry).unwrap();
for field_num in 1..=9 {
assert!(
!parsed_empty.has_field(field_num),
"Field {} should NOT be present",
field_num
);
}
}
#[test]
fn field_presence_partial_message() {
let desc = make_descriptor(
"Test",
vec![
make_field(1, "id", Type::Int32, false, None),
make_field(2, "name", Type::String, false, None),
make_field(3, "age", Type::Int32, false, None),
make_field(4, "email", Type::String, false, None),
],
);
let registry = MessageRegistry::from_descriptor(&desc);
let wire = &[8, 42, 24, 25];
let parsed = ParsedMessage::parse(wire, ®istry).unwrap();
assert!(parsed.has_field(1));
assert!(parsed.has_field(3));
assert_eq!(parsed.get_scalar(1), Some(&FieldValueRef::Int32(42)));
assert_eq!(parsed.get_scalar(3), Some(&FieldValueRef::Int32(25)));
assert!(!parsed.has_field(2));
assert!(!parsed.has_field(4));
assert_eq!(parsed.get_scalar(2), None);
assert_eq!(parsed.get_scalar(4), None);
}
#[test]
fn field_presence_nested_messages() {
let inner = make_descriptor(
"Inner",
vec![
make_field(1, "value", Type::Int32, false, None),
make_field(2, "flag", Type::Bool, false, None),
],
);
let mut outer = make_descriptor(
"Outer",
vec![
make_field(1, "id", Type::Int32, false, None),
make_field(2, "inner", Type::Message, false, Some(".Outer.Inner")),
],
);
outer.nested_type.push(inner);
let registry = MessageRegistry::from_descriptor(&outer);
let wire_no_inner = &[8, 100];
let parsed_no_inner = ParsedMessage::parse(wire_no_inner, ®istry).unwrap();
assert!(parsed_no_inner.has_field(1));
assert!(!parsed_no_inner.has_field(2));
assert!(parsed_no_inner.get_message(2).is_none());
let inner_wire = &[8, 42];
let mut wire_with_inner = vec![8, 100, 18, inner_wire.len() as u8];
wire_with_inner.extend_from_slice(inner_wire);
let parsed_with_inner = ParsedMessage::parse(&wire_with_inner, ®istry).unwrap();
assert!(parsed_with_inner.has_field(1));
assert!(parsed_with_inner.has_field(2));
let inner_msg = parsed_with_inner.get_message(2).unwrap();
assert!(inner_msg.has_field(1));
assert!(!inner_msg.has_field(2));
assert_eq!(inner_msg.get_scalar(1), Some(&FieldValueRef::Int32(42)));
assert_eq!(inner_msg.get_scalar(2), None);
}
#[test]
fn field_presence_repeated_and_map_return_empty() {
let item = make_descriptor("Item", vec![make_field(1, "id", Type::Int32, false, None)]);
let map_entry = make_map_entry_descriptor("MapEntry", Type::String, Type::Int32);
let mut desc = make_descriptor(
"Test",
vec![
make_field(1, "scalars", Type::Int32, true, None),
make_field(2, "messages", Type::Message, true, Some(".Test.Item")),
make_field(3, "map", Type::Message, true, Some(".Test.MapEntry")),
],
);
desc.nested_type.push(item);
desc.nested_type.push(map_entry);
let registry = MessageRegistry::from_descriptor(&desc);
let parsed = ParsedMessage::parse(&[], ®istry).unwrap();
assert!(parsed.get_repeated_scalars(1).is_empty());
assert!(parsed.get_repeated_messages(2).is_empty());
assert_eq!(parsed.get_map_entries_count(3), 0);
let wire = &[8, 1, 18, 2, 8, 42, 26, 5, 10, 1, b'k', 16, 99];
let parsed_with_values = ParsedMessage::parse(wire, ®istry).unwrap();
assert_eq!(parsed_with_values.get_repeated_scalars(1).len(), 1);
assert_eq!(parsed_with_values.get_repeated_messages(2).len(), 1);
assert_eq!(parsed_with_values.get_map_entries_count(3), 1);
}
#[test]
fn parse_ignores_unknown_fields() {
let desc = make_descriptor("Test", vec![make_field(1, "id", Type::Int32, false, None)]);
let registry = MessageRegistry::from_descriptor(&desc);
let wire = &[8, 42, 0x98, 0x06, 123];
let parsed = ParsedMessage::parse(wire, ®istry).unwrap();
assert!(parsed.has_field(1));
assert_eq!(parsed.get_scalar(1), Some(&FieldValueRef::Int32(42)));
assert!(!parsed.has_field(99));
assert_eq!(parsed.get_scalar(99), None);
}
#[test]
fn parse_large_field_number() {
assert_eq!(MAX_INLINE_CAPACITY, 128);
let desc = make_descriptor(
"Test",
vec![
make_field(127, "at_boundary", Type::Int32, false, None),
make_field(128, "first_large", Type::Int32, false, None),
make_field(200, "big", Type::String, false, None),
],
);
let registry = MessageRegistry::from_descriptor(&desc);
let wire = &[
0xF8, 0x07, 127, 0x80, 0x08, 0x80, 0x01, 0xC2, 0x0C, 3, b'a', b'b', b'c', ];
let parsed = ParsedMessage::parse(wire, ®istry).unwrap();
assert!(parsed.has_field(127));
assert_eq!(parsed.get_scalar(127), Some(&FieldValueRef::Int32(127)));
assert!(parsed.has_field(128));
assert_eq!(parsed.get_scalar(128), Some(&FieldValueRef::Int32(128)));
assert!(parsed.has_field(200));
assert_eq!(parsed.get_scalar(200), Some(&FieldValueRef::String("abc")));
}
#[test]
fn parse_empty_nested_message() {
let inner = make_descriptor(
"Inner",
vec![
make_field(1, "value", Type::Int32, false, None),
make_field(2, "name", Type::String, false, None),
],
);
let mut outer = make_descriptor(
"Outer",
vec![
make_field(1, "id", Type::Int32, false, None),
make_field(2, "inner", Type::Message, false, Some(".Outer.Inner")),
],
);
outer.nested_type.push(inner);
let registry = MessageRegistry::from_descriptor(&outer);
let wire = &[8, 42, 18, 0];
let parsed = ParsedMessage::parse(wire, ®istry).unwrap();
assert!(parsed.has_field(1));
assert_eq!(parsed.get_scalar(1), Some(&FieldValueRef::Int32(42)));
assert!(parsed.has_field(2));
let inner_msg = parsed.get_message(2).expect("inner should exist");
assert!(!inner_msg.has_field(1));
assert!(!inner_msg.has_field(2));
assert_eq!(inner_msg.get_scalar(1), None);
assert_eq!(inner_msg.get_scalar(2), None);
}
#[test]
fn parse_multiple_map_entries_and_duplicate_keys() {
let map_entry = make_map_entry_descriptor("MapEntry", Type::String, Type::Int32);
let mut outer = make_descriptor(
"Outer",
vec![make_field(
1,
"items",
Type::Message,
true,
Some(".Outer.MapEntry"),
)],
);
outer.nested_type.push(map_entry);
let registry = MessageRegistry::from_descriptor(&outer);
let wire = &[
10, 5, 10, 1, b'a', 16, 1, 10, 5, 10, 1, b'b', 16, 2, 10, 5, 10, 1, b'c', 16, 3, ];
let parsed = ParsedMessage::parse(wire, ®istry).unwrap();
assert_eq!(parsed.get_map_entries_count(1), 3);
let entries: std::collections::HashMap<_, _> = parsed.get_map_entries(1).collect();
assert!(matches!(
entries.get(&MapKeyRef::String("a")),
Some(ParsedMapValue::Scalar(FieldValueRef::Int32(1)))
));
assert!(matches!(
entries.get(&MapKeyRef::String("b")),
Some(ParsedMapValue::Scalar(FieldValueRef::Int32(2)))
));
assert!(matches!(
entries.get(&MapKeyRef::String("c")),
Some(ParsedMapValue::Scalar(FieldValueRef::Int32(3)))
));
let wire_dup = &[
10, 5, 10, 1, b'x', 16, 10, 10, 5, 10, 1, b'x', 16, 20, ];
let parsed_dup = ParsedMessage::parse(wire_dup, ®istry).unwrap();
assert_eq!(parsed_dup.get_map_entries_count(1), 1);
let dup_entries: Vec<_> = parsed_dup.get_map_entries(1).collect();
assert_eq!(*dup_entries[0].0, MapKeyRef::String("x"));
assert!(matches!(
dup_entries[0].1,
ParsedMapValue::Scalar(FieldValueRef::Int32(20))
));
}
#[test]
fn parse_map_with_repeated_message_values() {
let value_msg = make_descriptor(
"ValueMsg",
vec![
make_field(1, "id", Type::Int32, false, None),
make_field(2, "tags", Type::String, true, None),
],
);
let mut map_entry = make_descriptor(
"MapEntry",
vec![
make_field(1, "key", Type::String, false, None),
make_field(2, "value", Type::Message, false, Some(".Outer.ValueMsg")),
],
);
map_entry.options = Some(MessageOptions {
map_entry: Some(true),
..Default::default()
});
let mut outer = make_descriptor(
"Outer",
vec![make_field(
1,
"items",
Type::Message,
true,
Some(".Outer.MapEntry"),
)],
);
outer.nested_type.push(map_entry);
outer.nested_type.push(value_msg);
let registry = MessageRegistry::from_descriptor(&outer);
let value_msg_bytes = &[
8, 99, 18, 1, b'a', 18, 1, b'b', ];
let mut entry_wire = vec![
10,
2,
b'k',
b'1', 18,
value_msg_bytes.len() as u8, ];
entry_wire.extend_from_slice(value_msg_bytes);
let mut wire = vec![10, entry_wire.len() as u8]; wire.extend_from_slice(&entry_wire);
let parsed = ParsedMessage::parse(&wire, ®istry).unwrap();
assert_eq!(parsed.get_map_entries_count(1), 1);
let entries: Vec<_> = parsed.get_map_entries(1).collect();
assert_eq!(*entries[0].0, MapKeyRef::String("k1"));
match entries[0].1 {
ParsedMapValue::Message(msg) => {
assert_eq!(msg.get_scalar(1), Some(&FieldValueRef::Int32(99)));
let tags = msg.get_repeated_scalars(2);
assert_eq!(tags.len(), 2);
assert_eq!(tags[0], FieldValueRef::String("a"));
assert_eq!(tags[1], FieldValueRef::String("b"));
}
_ => panic!("Expected message value"),
}
}
#[test]
fn parse_multibyte_utf8_strings() {
let desc = make_descriptor(
"Test",
vec![
make_field(1, "emoji", Type::String, false, None),
make_field(2, "cjk", Type::String, false, None),
make_field(3, "mixed", Type::String, false, None),
],
);
let registry = MessageRegistry::from_descriptor(&desc);
let emoji = "Hello 👋 World";
let mut wire = vec![10, emoji.len() as u8];
wire.extend_from_slice(emoji.as_bytes());
let cjk = "你好世界";
wire.push(18); wire.push(cjk.len() as u8);
wire.extend_from_slice(cjk.as_bytes());
let mixed = "Привет🌍World";
wire.push(26); wire.push(mixed.len() as u8);
wire.extend_from_slice(mixed.as_bytes());
let parsed = ParsedMessage::parse(&wire, ®istry).unwrap();
assert_eq!(parsed.get_scalar(1), Some(&FieldValueRef::String(emoji)));
assert_eq!(parsed.get_scalar(2), Some(&FieldValueRef::String(cjk)));
assert_eq!(parsed.get_scalar(3), Some(&FieldValueRef::String(mixed)));
}
#[test]
fn parse_singular_message_merges_scalars_per_spec() {
let inner = make_descriptor(
"Inner",
vec![
make_field(1, "x", Type::Int32, false, None),
make_field(2, "y", Type::Int32, false, None),
make_field(3, "z", Type::String, false, None),
],
);
let mut outer = make_descriptor(
"Outer",
vec![make_field(
1,
"inner",
Type::Message,
false,
Some(".Outer.Inner"),
)],
);
outer.nested_type.push(inner);
let registry = MessageRegistry::from_descriptor(&outer);
let mut wire = ld(1, &[16, 1, 26, 2, b'z', b'1']);
wire.extend(ld(1, &[8, 10, 16, 2]));
let m = ParsedMessage::parse(&wire, ®istry).unwrap();
let i = m.get_message(1).expect("inner");
assert_eq!(i.get_scalar(1), Some(&FieldValueRef::Int32(10))); assert_eq!(i.get_scalar(2), Some(&FieldValueRef::Int32(2))); assert_eq!(i.get_scalar(3), Some(&FieldValueRef::String("z1"))); }
#[test]
fn parse_singular_message_merge_recurses_through_nested() {
let c = make_descriptor(
"C",
vec![
make_field(1, "x", Type::Int32, false, None),
make_field(2, "y", Type::Int32, false, None),
],
);
let mut b = make_descriptor(
"B",
vec![make_field(1, "c", Type::Message, false, Some(".A.B.C"))],
);
b.nested_type.push(c);
let mut a = make_descriptor(
"A",
vec![make_field(1, "b", Type::Message, false, Some(".A.B"))],
);
a.nested_type.push(b);
let registry = MessageRegistry::from_descriptor(&a);
let mut wire = ld(1, &ld(1, &[8, 7])); wire.extend(ld(1, &ld(1, &[16, 9])));
let parsed = ParsedMessage::parse(&wire, ®istry).unwrap();
let c = parsed.get_message(1).expect("b").get_message(1).expect("c");
assert_eq!(c.get_scalar(1), Some(&FieldValueRef::Int32(7)));
assert_eq!(c.get_scalar(2), Some(&FieldValueRef::Int32(9)));
}
#[test]
fn parse_singular_message_merge_handles_oneofs() {
let inner = make_descriptor("Inner", vec![make_field(1, "x", Type::Int32, false, None)]);
let mut wrapper = make_descriptor_with_oneofs(
"Wrapper",
vec![
make_oneof_field(1, "a", Type::Int32, false, None, Some(0)),
make_oneof_field(2, "b", Type::String, false, None, Some(0)),
make_oneof_field(
3,
"msg",
Type::Message,
false,
Some(".Outer.Wrapper.Inner"),
Some(0),
),
],
vec!["payload"],
);
wrapper.nested_type.push(inner);
let mut outer = make_descriptor(
"Outer",
vec![make_field(
1,
"w",
Type::Message,
false,
Some(".Outer.Wrapper"),
)],
);
outer.nested_type.push(wrapper);
let registry = MessageRegistry::from_descriptor(&outer);
let mut wire = ld(1, &[8, 7]);
wire.extend(ld(1, &ld(3, &[8, 1])));
let p = ParsedMessage::parse(&wire, ®istry).unwrap();
let w = p.get_message(1).unwrap();
assert!(!w.has_field(1) && !w.has_field(2));
assert_eq!(
w.get_message(3).unwrap().get_scalar(1),
Some(&FieldValueRef::Int32(1))
);
let mut wire = ld(1, &ld(3, &[8, 1]));
wire.extend(ld(1, &ld(3, &[8, 10])));
let p = ParsedMessage::parse(&wire, ®istry).unwrap();
assert_eq!(
p.get_message(1)
.unwrap()
.get_message(3)
.unwrap()
.get_scalar(1),
Some(&FieldValueRef::Int32(10))
);
let mut wire = ld(1, &ld(3, &[8, 1]));
wire.extend(ld(1, &[18, 2, b'h', b'i']));
let p = ParsedMessage::parse(&wire, ®istry).unwrap();
let w = p.get_message(1).unwrap();
assert!(w.get_message(3).is_none());
assert_eq!(w.get_scalar(2), Some(&FieldValueRef::String("hi")));
}
#[test]
fn parse_singular_message_merges_complex_variants() {
let item = make_descriptor("Item", vec![make_field(1, "v", Type::Int32, false, None)]);
let map_entry = make_map_entry_descriptor("CE", Type::String, Type::Int32);
let mut wrapper = make_descriptor(
"Wrapper",
vec![
make_field(1, "vals", Type::Int32, true, None),
make_field(2, "items", Type::Message, true, Some(".Outer.Wrapper.Item")),
make_field(3, "counts", Type::Message, true, Some(".Outer.Wrapper.CE")),
],
);
wrapper.nested_type.push(item);
wrapper.nested_type.push(map_entry);
let mut outer = make_descriptor(
"Outer",
vec![make_field(
1,
"w",
Type::Message,
false,
Some(".Outer.Wrapper"),
)],
);
outer.nested_type.push(wrapper);
let registry = MessageRegistry::from_descriptor(&outer);
let mut w1 = vec![8u8, 1, 8, 2];
w1.extend(ld(2, &[8, 1]));
w1.extend(ld(3, &[10, 1, b'a', 16, 10]));
let mut w2 = vec![8u8, 3];
w2.extend(ld(2, &[8, 2]));
w2.extend(ld(3, &[10, 1, b'a', 16, 99]));
w2.extend(ld(3, &[10, 1, b'b', 16, 20]));
let mut wire = ld(1, &w1);
wire.extend(ld(1, &w2));
let parsed = ParsedMessage::parse(&wire, ®istry).unwrap();
let w = parsed.get_message(1).expect("w");
assert_eq!(
w.get_repeated_scalars(1),
&[
FieldValueRef::Int32(1),
FieldValueRef::Int32(2),
FieldValueRef::Int32(3),
]
);
let item_vs: Vec<_> = w
.get_repeated_messages(2)
.iter()
.map(|m| m.get_scalar(1).copied())
.collect();
assert_eq!(
item_vs,
vec![Some(FieldValueRef::Int32(1)), Some(FieldValueRef::Int32(2))]
);
let counts: std::collections::HashMap<_, i32> = w
.get_map_entries(3)
.map(|(k, v)| match v {
ParsedMapValue::Scalar(FieldValueRef::Int32(n)) => (*k, *n),
_ => panic!("non-int value"),
})
.collect();
assert_eq!(counts.get(&MapKeyRef::String("a")), Some(&99)); assert_eq!(counts.get(&MapKeyRef::String("b")), Some(&20));
}
#[test]
fn parse_singular_message_merge_preserves_untouched_oneof() {
let mut wrapper = make_descriptor_with_oneofs(
"Wrapper",
vec![
make_oneof_field(1, "a", Type::Int32, false, None, Some(0)),
make_oneof_field(2, "b", Type::String, false, None, Some(0)),
make_field(4, "always", Type::Int32, false, None),
],
vec!["payload"],
);
let mut outer = make_descriptor(
"Outer",
vec![make_field(
1,
"w",
Type::Message,
false,
Some(".Outer.Wrapper"),
)],
);
outer.nested_type.push(std::mem::take(&mut wrapper));
let registry = MessageRegistry::from_descriptor(&outer);
let mut wire = ld(1, &[8, 7]);
wire.extend(ld(1, &[32, 42]));
let parsed = ParsedMessage::parse(&wire, ®istry).unwrap();
let w = parsed.get_message(1).unwrap();
assert_eq!(w.get_scalar(1), Some(&FieldValueRef::Int32(7)));
assert_eq!(w.get_scalar(4), Some(&FieldValueRef::Int32(42)));
assert!(!w.has_field(2));
}
#[test]
fn parse_singular_message_merge_installs_into_empty_complex_slots() {
let inner = make_descriptor("Inner", vec![make_field(1, "x", Type::Int32, false, None)]);
let map_entry = make_map_entry_descriptor("CE", Type::String, Type::Int32);
let mut wrapper = make_descriptor(
"Wrapper",
vec![
make_field(1, "id", Type::Int32, false, None),
make_field(
2,
"inner",
Type::Message,
false,
Some(".Outer.Wrapper.Inner"),
),
make_field(3, "counts", Type::Message, true, Some(".Outer.Wrapper.CE")),
],
);
wrapper.nested_type.push(inner);
wrapper.nested_type.push(map_entry);
let mut outer = make_descriptor(
"Outer",
vec![make_field(
1,
"w",
Type::Message,
false,
Some(".Outer.Wrapper"),
)],
);
outer.nested_type.push(wrapper);
let registry = MessageRegistry::from_descriptor(&outer);
let mut wire = ld(1, &[8, 1]);
let mut w2 = ld(2, &[8, 5]);
w2.extend(ld(3, &[10, 1, b'a', 16, 7]));
wire.extend(ld(1, &w2));
let parsed = ParsedMessage::parse(&wire, ®istry).unwrap();
let w = parsed.get_message(1).unwrap();
assert_eq!(w.get_scalar(1), Some(&FieldValueRef::Int32(1))); assert_eq!(
w.get_message(2).unwrap().get_scalar(1),
Some(&FieldValueRef::Int32(5))
); let counts: Vec<_> = w.get_map_entries(3).collect();
assert_eq!(counts.len(), 1);
assert_eq!(*counts[0].0, MapKeyRef::String("a"));
}
#[test]
fn parse_singular_message_merge_no_op_when_other_is_empty() {
let wrapper = make_descriptor(
"Wrapper",
vec![make_field(1, "id", Type::Int32, false, None)],
);
let mut outer = make_descriptor(
"Outer",
vec![make_field(
1,
"w",
Type::Message,
false,
Some(".Outer.Wrapper"),
)],
);
outer.nested_type.push(wrapper);
let registry = MessageRegistry::from_descriptor(&outer);
let mut wire = ld(1, &[8, 10]);
wire.extend(ld(1, &[]));
let parsed = ParsedMessage::parse(&wire, ®istry).unwrap();
let w = parsed.get_message(1).unwrap();
assert_eq!(w.get_scalar(1), Some(&FieldValueRef::Int32(10)));
}
#[test]
fn parse_map_entry_single_message_value_field_installs() {
let inner = make_descriptor("Inner", vec![make_field(1, "x", Type::Int32, false, None)]);
let mut map_entry = make_descriptor(
"ME",
vec![
make_field(1, "key", Type::String, false, None),
make_field(2, "value", Type::Message, false, Some(".Outer.Inner")),
],
);
map_entry.options = Some(MessageOptions {
map_entry: Some(true),
..Default::default()
});
let mut outer = make_descriptor(
"Outer",
vec![make_field(1, "m", Type::Message, true, Some(".Outer.ME"))],
);
outer.nested_type.push(inner);
outer.nested_type.push(map_entry);
let registry = MessageRegistry::from_descriptor(&outer);
let mut entry = vec![10u8, 1, b'k'];
entry.extend(ld(2, &[8, 42]));
let wire = ld(1, &entry);
let parsed = ParsedMessage::parse(&wire, ®istry).unwrap();
let entries: Vec<_> = parsed.get_map_entries(1).collect();
assert_eq!(entries.len(), 1);
let (k, v) = entries[0];
assert_eq!(*k, MapKeyRef::String("k"));
let ParsedMapValue::Message(m) = v else {
panic!("expected Message value");
};
assert_eq!(m.get_scalar(1), Some(&FieldValueRef::Int32(42)));
}
#[test]
fn parse_map_entry_repeated_value_field_merges_for_messages() {
let inner = make_descriptor(
"Inner",
vec![
make_field(1, "x", Type::Int32, false, None),
make_field(2, "y", Type::Int32, false, None),
],
);
let mut map_entry = make_descriptor(
"ME",
vec![
make_field(1, "key", Type::String, false, None),
make_field(2, "value", Type::Message, false, Some(".Outer.Inner")),
],
);
map_entry.options = Some(MessageOptions {
map_entry: Some(true),
..Default::default()
});
let mut outer = make_descriptor(
"Outer",
vec![make_field(1, "m", Type::Message, true, Some(".Outer.ME"))],
);
outer.nested_type.push(inner);
outer.nested_type.push(map_entry);
let registry = MessageRegistry::from_descriptor(&outer);
let mut entry = vec![10u8, 1, b'k'];
entry.extend(ld(2, &[8, 10]));
entry.extend(ld(2, &[16, 20]));
let wire = ld(1, &entry);
let parsed = ParsedMessage::parse(&wire, ®istry).unwrap();
let entries: Vec<_> = parsed.get_map_entries(1).collect();
assert_eq!(entries.len(), 1);
let (k, v) = entries[0];
assert_eq!(*k, MapKeyRef::String("k"));
let ParsedMapValue::Message(m) = v else {
panic!("expected Message value");
};
assert_eq!(m.get_scalar(1), Some(&FieldValueRef::Int32(10)));
assert_eq!(m.get_scalar(2), Some(&FieldValueRef::Int32(20)));
}
#[test]
fn parse_map_entry_with_extra_fields() {
let mut map_entry = make_descriptor(
"MapEntry",
vec![
make_field(1, "key", Type::String, false, None),
make_field(2, "value", Type::Int32, false, None),
make_field(3, "extra", Type::String, false, None), ],
);
map_entry.options = Some(MessageOptions {
map_entry: Some(true),
..Default::default()
});
let mut outer = make_descriptor(
"Outer",
vec![make_field(
1,
"items",
Type::Message,
true,
Some(".Outer.MapEntry"),
)],
);
outer.nested_type.push(map_entry);
let registry = MessageRegistry::from_descriptor(&outer);
let entry_wire = &[
10, 1, b'k', 16, 42, 26, 7, b'i', b'g', b'n', b'o', b'r', b'e', b'd', ];
let mut wire = vec![10, entry_wire.len() as u8]; wire.extend_from_slice(entry_wire);
let parsed = ParsedMessage::parse(&wire, ®istry).unwrap();
assert_eq!(parsed.get_map_entries_count(1), 1);
let entries: Vec<_> = parsed.get_map_entries(1).collect();
assert_eq!(*entries[0].0, MapKeyRef::String("k"));
match entries[0].1 {
ParsedMapValue::Scalar(v) => assert_eq!(v, &FieldValueRef::Int32(42)),
_ => panic!("Expected scalar value"),
}
}
#[test]
fn map_key_invalid_types_rejected() {
let invalid_key_types = vec![
("float", Type::Float),
("double", Type::Double),
("bytes", Type::Bytes),
];
for (type_name, key_type) in invalid_key_types {
let map_entry = make_map_entry_descriptor("MapEntry", key_type, Type::Int32);
let mut outer = make_descriptor(
"Outer",
vec![make_field(
1,
"items",
Type::Message,
true,
Some(".Outer.MapEntry"),
)],
);
outer.nested_type.push(map_entry);
let registry = MessageRegistry::from_descriptor(&outer);
let entry_wire: Vec<u8> = match key_type {
Type::Float => vec![
13, 0, 0, 128, 63, 16, 42, ],
Type::Double => vec![
9, 0, 0, 0, 0, 0, 0, 240, 63, 16, 42, ],
Type::Bytes => vec![
10, 3, b'a', b'b', b'c', 16, 42, ],
_ => unreachable!(),
};
let mut wire = vec![10, entry_wire.len() as u8];
wire.extend_from_slice(&entry_wire);
let result = ParsedMessage::parse(&wire, ®istry);
assert!(
result.is_err(),
"Expected error for invalid map key type: {}",
type_name
);
assert!(
matches!(result, Err(ParseError::InvalidMapKeyType { .. })),
"Expected InvalidMapKeyType error for {}, got {:?}",
type_name,
result
);
}
}
#[test]
fn map_key_valid_types_all_supported() {
let valid_key_cases: Vec<(&str, Type, &[u8], MapKeyRef)> = vec![
(
"string",
Type::String,
&[10, 3, b'f', b'o', b'o'], MapKeyRef::String("foo"),
),
(
"int32",
Type::Int32,
&[8, 42], MapKeyRef::Int32(42),
),
(
"int64",
Type::Int64,
&[8, 0x80, 0x01], MapKeyRef::Int64(128),
),
(
"uint32",
Type::Uint32,
&[8, 100], MapKeyRef::UInt32(100),
),
(
"uint64",
Type::Uint64,
&[8, 200, 1], MapKeyRef::UInt64(200),
),
(
"sint32",
Type::Sint32,
&[8, 1], MapKeyRef::Int32(-1),
),
(
"sint64",
Type::Sint64,
&[8, 3], MapKeyRef::Int64(-2),
),
(
"fixed32",
Type::Fixed32,
&[13, 0x78, 0x56, 0x34, 0x12], MapKeyRef::UInt32(0x12345678),
),
(
"fixed64",
Type::Fixed64,
&[9, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01], MapKeyRef::UInt64(0x0102030405060708),
),
(
"sfixed32",
Type::Sfixed32,
&[13, 0xFF, 0xFF, 0xFF, 0xFF], MapKeyRef::Int32(-1),
),
(
"sfixed64",
Type::Sfixed64,
&[9, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF], MapKeyRef::Int64(-1),
),
(
"bool_true",
Type::Bool,
&[8, 1], MapKeyRef::Bool(true),
),
(
"bool_false",
Type::Bool,
&[8, 0], MapKeyRef::Bool(false),
),
];
for (case_name, key_type, key_wire, expected_key) in valid_key_cases {
let map_entry = make_map_entry_descriptor("MapEntry", key_type, Type::Int32);
let mut outer = make_descriptor(
"Outer",
vec![make_field(
1,
"items",
Type::Message,
true,
Some(".Outer.MapEntry"),
)],
);
outer.nested_type.push(map_entry);
let registry = MessageRegistry::from_descriptor(&outer);
let mut entry_wire = key_wire.to_vec();
entry_wire.extend_from_slice(&[16, 99]);
let mut wire = vec![10, entry_wire.len() as u8];
wire.extend_from_slice(&entry_wire);
let parsed = ParsedMessage::parse(&wire, ®istry)
.unwrap_or_else(|e| panic!("Failed to parse for case {}: {:?}", case_name, e));
assert_eq!(parsed.get_map_entries_count(1), 1, "case: {}", case_name);
let entries: Vec<_> = parsed.get_map_entries(1).collect();
assert_eq!(
*entries[0].0, expected_key,
"case: {} key mismatch",
case_name
);
match entries[0].1 {
ParsedMapValue::Scalar(v) => {
assert_eq!(v, &FieldValueRef::Int32(99), "case: {} value", case_name)
}
_ => panic!("Expected scalar value for case {}", case_name),
}
}
}
fn make_oneof_field(
number: i32,
name: &str,
field_type: Type,
repeated: bool,
type_name: Option<&str>,
oneof_index: Option<i32>,
) -> FieldDescriptorProto {
let mut field = make_field(number, name, field_type, repeated, type_name);
field.oneof_index = oneof_index;
field
}
fn make_descriptor_with_oneofs(
name: &str,
fields: Vec<FieldDescriptorProto>,
oneof_names: Vec<&str>,
) -> DescriptorProto {
let mut desc = make_descriptor(name, fields);
desc.oneof_decl = oneof_names
.into_iter()
.map(|n| OneofDescriptorProto {
name: Some(n.to_string()),
options: None,
})
.collect();
desc
}
#[test]
fn oneof_last_writer_wins_scalars() {
let desc = make_descriptor_with_oneofs(
"Test",
vec![
make_field(1, "always_present", Type::Int32, false, None),
make_oneof_field(2, "name", Type::String, false, None, Some(0)),
make_oneof_field(3, "id", Type::Int32, false, None, Some(0)),
],
vec!["value"],
);
let registry = MessageRegistry::from_descriptor(&desc);
let wire = &[
8, 42, 18, 2, b'h', b'i', 24, 99, ];
let parsed = ParsedMessage::parse(wire, ®istry).unwrap();
assert_eq!(parsed.get_scalar(1), Some(&FieldValueRef::Int32(42)));
assert!(!parsed.has_field(2));
assert_eq!(parsed.get_scalar(2), None);
assert_eq!(parsed.get_scalar(3), Some(&FieldValueRef::Int32(99)));
}
#[test]
fn oneof_last_writer_wins_reverse_order() {
let desc = make_descriptor_with_oneofs(
"Test",
vec![
make_oneof_field(1, "name", Type::String, false, None, Some(0)),
make_oneof_field(2, "id", Type::Int32, false, None, Some(0)),
],
vec!["value"],
);
let registry = MessageRegistry::from_descriptor(&desc);
let wire = &[
16, 99, 10, 6, b'w', b'i', b'n', b'n', b'e', b'r', ];
let parsed = ParsedMessage::parse(wire, ®istry).unwrap();
assert_eq!(parsed.get_scalar(1), Some(&FieldValueRef::String("winner")));
assert!(!parsed.has_field(2));
}
#[test]
fn oneof_mixed_scalar_and_message() {
let inner = make_descriptor("Inner", vec![make_field(1, "x", Type::Int32, false, None)]);
let mut desc = make_descriptor_with_oneofs(
"Outer",
vec![
make_field(1, "tag", Type::Int32, false, None),
make_oneof_field(2, "str_val", Type::String, false, None, Some(0)),
make_oneof_field(
3,
"msg_val",
Type::Message,
false,
Some(".Outer.Inner"),
Some(0),
),
],
vec!["payload"],
);
desc.nested_type.push(inner);
let registry = MessageRegistry::from_descriptor(&desc);
let inner_wire = &[8, 42]; let mut wire = vec![
8,
1, 18,
5,
b'h',
b'e',
b'l',
b'l',
b'o', 26,
inner_wire.len() as u8, ];
wire.extend_from_slice(inner_wire);
let parsed = ParsedMessage::parse(&wire, ®istry).unwrap();
assert_eq!(parsed.get_scalar(1), Some(&FieldValueRef::Int32(1)));
assert!(!parsed.has_field(2));
let msg = parsed.get_message(3).expect("msg_val should be present");
assert_eq!(msg.get_scalar(1), Some(&FieldValueRef::Int32(42)));
}
#[test]
fn oneof_message_then_scalar_clears_message() {
let inner = make_descriptor("Inner", vec![make_field(1, "x", Type::Int32, false, None)]);
let mut desc = make_descriptor_with_oneofs(
"Outer",
vec![
make_oneof_field(2, "str_val", Type::String, false, None, Some(0)),
make_oneof_field(
3,
"msg_val",
Type::Message,
false,
Some(".Outer.Inner"),
Some(0),
),
],
vec!["payload"],
);
desc.nested_type.push(inner);
let registry = MessageRegistry::from_descriptor(&desc);
let inner_wire = &[8, 42];
let mut wire = vec![26, inner_wire.len() as u8];
wire.extend_from_slice(inner_wire);
wire.extend_from_slice(&[18, 4, b'w', b'i', b'n', b's']);
let parsed = ParsedMessage::parse(&wire, ®istry).unwrap();
assert_eq!(parsed.get_scalar(2), Some(&FieldValueRef::String("wins")));
assert!(!parsed.has_field(3));
assert!(parsed.get_message(3).is_none());
}
#[test]
fn oneof_non_oneof_fields_unaffected() {
let desc = make_descriptor_with_oneofs(
"Test",
vec![
make_field(1, "regular_a", Type::Int32, false, None),
make_field(2, "regular_b", Type::String, false, None),
make_oneof_field(3, "choice_a", Type::Int32, false, None, Some(0)),
make_oneof_field(4, "choice_b", Type::Int32, false, None, Some(0)),
],
vec!["choice"],
);
let registry = MessageRegistry::from_descriptor(&desc);
let wire = &[
8, 1, 18, 2, b'o', b'k', 24, 10, 32, 20, ];
let parsed = ParsedMessage::parse(wire, ®istry).unwrap();
assert_eq!(parsed.get_scalar(1), Some(&FieldValueRef::Int32(1)));
assert_eq!(parsed.get_scalar(2), Some(&FieldValueRef::String("ok")));
assert!(!parsed.has_field(3));
assert_eq!(parsed.get_scalar(4), Some(&FieldValueRef::Int32(20)));
}
#[test]
fn oneof_proto3_optional_excluded() {
let mut field2 = make_oneof_field(2, "opt_field", Type::Int32, false, None, Some(0));
field2.proto3_optional = Some(true);
let desc = make_descriptor_with_oneofs(
"Test",
vec![
make_oneof_field(1, "real_a", Type::Int32, false, None, Some(0)),
field2,
],
vec!["_opt_field"],
);
let registry = MessageRegistry::from_descriptor(&desc);
let wire = &[8, 10, 16, 20];
let parsed = ParsedMessage::parse(wire, ®istry).unwrap();
assert_eq!(parsed.get_scalar(1), Some(&FieldValueRef::Int32(10)));
assert_eq!(parsed.get_scalar(2), Some(&FieldValueRef::Int32(20)));
}
#[test]
fn get_field_returns_scalar() {
let desc = make_descriptor("Test", vec![make_field(1, "id", Type::Int32, false, None)]);
let registry = MessageRegistry::from_descriptor(&desc);
let parsed = ParsedMessage::parse(&[8, 42], ®istry).unwrap();
let field = parsed.get_field(1).unwrap();
match field {
ParsedFieldValue::Scalar(FieldValueRef::Int32(42)) => {}
other => panic!("Expected Scalar(Int32(42)), got {:?}", other),
}
}
#[test]
fn get_field_returns_message() {
let inner = make_descriptor("Inner", vec![make_field(1, "a", Type::Int32, false, None)]);
let mut outer = make_descriptor(
"Outer",
vec![make_field(
1,
"inner",
Type::Message,
false,
Some(".Outer.Inner"),
)],
);
outer.nested_type.push(inner);
let registry = MessageRegistry::from_descriptor(&outer);
let wire = &[10, 2, 8, 7];
let parsed = ParsedMessage::parse(wire, ®istry).unwrap();
let field = parsed.get_field(1).unwrap();
match field {
ParsedFieldValue::Complex(ComplexType::Message(msg)) => {
assert_eq!(msg.get_scalar(1), Some(&FieldValueRef::Int32(7)));
}
other => panic!("Expected Message(Message(_)), got {:?}", other),
}
}
#[test]
fn get_field_returns_repeated() {
let desc = make_descriptor("Test", vec![make_field(1, "nums", Type::Int32, true, None)]);
let registry = MessageRegistry::from_descriptor(&desc);
let parsed = ParsedMessage::parse(&[8, 1, 8, 2], ®istry).unwrap();
let field = parsed.get_field(1).unwrap();
match field {
ParsedFieldValue::Complex(ComplexType::RepeatedScalar(v)) => {
assert_eq!(v.len(), 2);
}
other => panic!("Expected RepeatedScalar, got {:?}", other),
}
}
#[test]
fn get_field_returns_empty_for_unset_complex() {
let desc = make_descriptor("Test", vec![make_field(1, "nums", Type::Int32, true, None)]);
let registry = MessageRegistry::from_descriptor(&desc);
let parsed = ParsedMessage::parse(&[], ®istry).unwrap();
let field = parsed.get_field(1).unwrap();
match field {
ParsedFieldValue::Complex(ComplexType::Empty) => {}
other => panic!("Expected Message(Empty), got {:?}", other),
}
}
#[test]
fn get_field_returns_none_for_unset_scalar() {
let desc = make_descriptor("Test", vec![make_field(1, "id", Type::Int32, false, None)]);
let registry = MessageRegistry::from_descriptor(&desc);
let parsed = ParsedMessage::parse(&[], ®istry).unwrap();
assert!(parsed.get_field(1).is_none());
}
#[test]
fn get_field_returns_none_for_unknown() {
let desc = make_descriptor("Test", vec![make_field(1, "id", Type::Int32, false, None)]);
let registry = MessageRegistry::from_descriptor(&desc);
let parsed = ParsedMessage::parse(&[], ®istry).unwrap();
assert!(parsed.get_field(99).is_none());
}
}