use alloc::borrow::ToOwned;
use alloc::collections::BTreeMap;
use alloc::string::String;
use alloc::sync::Arc;
use alloc::vec::Vec;
use crate::{
DescriptorPool, EnumIndex, FieldDescriptor, FieldKind, MessageDescriptor, MessageIndex,
ScalarType, SingularKind,
};
use buffa::bytes::{Buf, BufMut};
use buffa::encoding::{
decode_unknown_field, decode_varint, encode_varint, skip_field_depth, Tag, WireType,
};
use buffa::types::{
decode_bool, decode_double, decode_fixed32, decode_fixed64, decode_float, decode_int32,
decode_int64, decode_sfixed32, decode_sfixed64, decode_sint32, decode_sint64, decode_uint32,
decode_uint64, encode_bool, encode_double, encode_fixed32, encode_fixed64, encode_float,
encode_int32, encode_int64, encode_sfixed32, encode_sfixed64, encode_sint32, encode_sint64,
encode_uint32, encode_uint64, int32_encoded_len, int64_encoded_len, sint32_encoded_len,
sint64_encoded_len, uint32_encoded_len, uint64_encoded_len,
};
use buffa::unknown_fields::UnknownFields;
use buffa::{DecodeError, Message, RECURSION_LIMIT};
use super::message::{ReflectCow, ReflectMessage, ReflectMessageMut};
use super::value::{MapKey, MapValue, Value, ValueRef};
#[derive(Clone)]
pub struct DynamicMessage {
pool: Arc<DescriptorPool>,
msg_idx: MessageIndex,
fields: BTreeMap<u32, Value>,
unknown: UnknownFields,
}
impl core::fmt::Debug for DynamicMessage {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.debug_struct("DynamicMessage")
.field("type", &self.message_descriptor().full_name)
.field("fields", &self.fields)
.finish_non_exhaustive()
}
}
impl PartialEq for DynamicMessage {
fn eq(&self, other: &Self) -> bool {
Arc::ptr_eq(&self.pool, &other.pool)
&& self.msg_idx == other.msg_idx
&& self.fields == other.fields
&& self.unknown.len() == other.unknown.len()
}
}
impl DynamicMessage {
#[must_use]
pub fn new(pool: Arc<DescriptorPool>, msg_idx: MessageIndex) -> Self {
Self {
pool,
msg_idx,
fields: BTreeMap::new(),
unknown: UnknownFields::new(),
}
}
#[must_use]
pub fn new_by_name(pool: Arc<DescriptorPool>, full_name: &str) -> Option<Self> {
let idx = pool.message_index(full_name)?;
Some(Self::new(pool, idx))
}
#[must_use]
pub fn pool(&self) -> &Arc<DescriptorPool> {
&self.pool
}
#[must_use]
pub fn message_index(&self) -> MessageIndex {
self.msg_idx
}
fn field_or_extension(&self, number: u32) -> Option<&FieldDescriptor> {
let md = self.message_descriptor();
if let Some(fd) = md.field(number) {
return Some(fd);
}
if md.in_extension_range(number) {
return self
.pool
.extension_for(self.msg_idx, number)
.map(crate::ExtensionDescriptor::field);
}
None
}
pub fn decode(
pool: Arc<DescriptorPool>,
msg_idx: MessageIndex,
bytes: &[u8],
) -> Result<Self, DecodeError> {
let mut msg = Self::new(pool, msg_idx);
msg.merge(bytes)?;
Ok(msg)
}
pub fn merge(&mut self, bytes: &[u8]) -> Result<(), DecodeError> {
let mut buf = bytes;
self.merge_buf(&mut buf, RECURSION_LIMIT)
}
fn merge_buf(&mut self, buf: &mut impl Buf, depth: u32) -> Result<(), DecodeError> {
while buf.has_remaining() {
let tag = Tag::decode(buf)?;
self.merge_one_field(tag, buf, depth)?;
}
Ok(())
}
fn merge_group(
&mut self,
buf: &mut impl Buf,
group_field_number: u32,
depth: u32,
) -> Result<(), DecodeError> {
loop {
let tag = Tag::decode(buf)?;
if tag.wire_type() == WireType::EndGroup {
if tag.field_number() != group_field_number {
return Err(DecodeError::InvalidEndGroup(tag.field_number()));
}
return Ok(());
}
self.merge_one_field(tag, buf, depth)?;
}
}
fn merge_one_field(
&mut self,
tag: Tag,
buf: &mut impl Buf,
depth: u32,
) -> Result<(), DecodeError> {
let number = tag.field_number();
let (kind, oneof_index, delimited) = match self.field_or_extension(number) {
Some(fd) => (fd.kind, fd.oneof_index, fd.delimited),
None => {
self.unknown.push(decode_unknown_field(tag, buf, depth)?);
return Ok(());
}
};
if !wire_type_compatible(kind, tag.wire_type(), delimited) {
self.unknown.push(decode_unknown_field(tag, buf, depth)?);
return Ok(());
}
match kind {
FieldKind::Singular(sk) => {
if let Some(oi) = oneof_index {
self.clear_other_oneof_members(oi, number);
}
if let SingularKind::Message(midx) = sk {
if let Some(Value::Message(_)) = self.fields.get(&number) {
return self.merge_into_existing_message(number, midx, tag, buf, depth);
}
}
let v = self.decode_element(sk, tag, buf, depth)?;
self.fields.insert(number, v);
}
FieldKind::List(sk) => {
self.merge_list_field(number, sk, tag, buf, depth)?;
}
FieldKind::Map { key, value } => {
self.merge_map_field(number, key, value, tag, buf, depth)?;
}
}
Ok(())
}
fn clear_other_oneof_members(&mut self, oi: u16, keep_number: u32) {
let md = self.message_descriptor();
let Some(o) = md.oneofs.get(oi as usize) else {
return;
};
let to_clear: alloc::vec::Vec<u32> = o
.field_indices
.iter()
.filter_map(|&fi| md.fields.get(fi as usize))
.map(|f| f.number)
.filter(|&n| n != keep_number)
.collect();
for n in to_clear {
self.fields.remove(&n);
}
}
fn merge_into_existing_message(
&mut self,
number: u32,
midx: MessageIndex,
tag: Tag,
buf: &mut impl Buf,
depth: u32,
) -> Result<(), DecodeError> {
let _ = midx;
let depth = depth
.checked_sub(1)
.ok_or(DecodeError::RecursionLimitExceeded)?;
let Some(Value::Message(mut existing)) = self.fields.remove(&number) else {
return Ok(());
};
let result = match tag.wire_type() {
WireType::LengthDelimited => {
let len = decode_varint(buf)?;
let len = usize::try_from(len).map_err(|_| DecodeError::MessageTooLarge)?;
if buf.remaining() < len {
return Err(DecodeError::UnexpectedEof);
}
let mut sub = buf.copy_to_bytes(len);
existing.merge_buf(&mut sub, depth)
}
WireType::StartGroup => existing.merge_group(buf, tag.field_number(), depth),
wt => Err(DecodeError::WireTypeMismatch {
field_number: number,
expected: WireType::LengthDelimited as u8,
actual: wt as u8,
}),
};
self.fields.insert(number, Value::Message(existing));
result
}
fn merge_list_field(
&mut self,
number: u32,
elem: SingularKind,
tag: Tag,
buf: &mut impl Buf,
depth: u32,
) -> Result<(), DecodeError> {
let list = match self
.fields
.entry(number)
.or_insert_with(|| Value::List(Vec::new()))
{
Value::List(l) => l,
other => {
*other = Value::List(Vec::new());
let Value::List(l) = other else {
unreachable!()
};
l
}
};
let packable = is_packable(elem);
if tag.wire_type() == WireType::LengthDelimited && packable {
let len = decode_varint(buf)?;
let len = usize::try_from(len).map_err(|_| DecodeError::MessageTooLarge)?;
if buf.remaining() < len {
return Err(DecodeError::UnexpectedEof);
}
let mut packed = buf.copy_to_bytes(len);
while packed.has_remaining() {
list.push(decode_packed_element(elem, number, &mut packed)?);
}
return Ok(());
}
let v = self.decode_element_no_alias(elem, tag, buf, depth)?;
if let Some(Value::List(l)) = self.fields.get_mut(&number) {
l.push(v);
} else {
self.fields.insert(number, Value::List(alloc::vec![v]));
}
Ok(())
}
fn merge_map_field(
&mut self,
number: u32,
key_ty: ScalarType,
value_kind: SingularKind,
tag: Tag,
buf: &mut impl Buf,
depth: u32,
) -> Result<(), DecodeError> {
if tag.wire_type() != WireType::LengthDelimited {
self.unknown.push(decode_unknown_field(tag, buf, depth)?);
return Ok(());
}
let len = decode_varint(buf)?;
let len = usize::try_from(len).map_err(|_| DecodeError::MessageTooLarge)?;
if buf.remaining() < len {
return Err(DecodeError::UnexpectedEof);
}
let mut entry = buf.copy_to_bytes(len);
let mut key: Option<MapKey> = None;
let mut value: Option<Value> = None;
while entry.has_remaining() {
let entry_tag = Tag::decode(&mut entry)?;
match entry_tag.field_number() {
1 => key = Some(decode_map_key(key_ty, entry_tag, &mut entry)?),
2 => {
value = Some(self.decode_element_no_alias(
value_kind,
entry_tag,
&mut entry,
depth.saturating_sub(1),
)?);
}
_ => skip_field_depth(entry_tag, &mut entry, depth)?,
}
}
let k = key.unwrap_or_else(|| default_map_key(key_ty));
let v = value.unwrap_or_else(|| default_value(value_kind, &self.pool));
match self
.fields
.entry(number)
.or_insert_with(|| Value::Map(MapValue::new()))
{
Value::Map(m) => {
m.insert(k, v);
}
other => {
let mut m = MapValue::new();
m.insert(k, v);
*other = Value::Map(m);
}
}
Ok(())
}
fn decode_element(
&self,
kind: SingularKind,
tag: Tag,
buf: &mut impl Buf,
depth: u32,
) -> Result<Value, DecodeError> {
self.decode_element_no_alias(kind, tag, buf, depth)
}
fn decode_element_no_alias(
&self,
kind: SingularKind,
tag: Tag,
buf: &mut impl Buf,
depth: u32,
) -> Result<Value, DecodeError> {
match kind {
SingularKind::Scalar(s) => decode_scalar(s, tag.wire_type(), buf),
SingularKind::Enum(_) => {
Ok(Value::EnumNumber(decode_int32(buf)?))
}
SingularKind::Message(midx) => {
let mut nested = DynamicMessage::new(Arc::clone(&self.pool), midx);
let depth = depth
.checked_sub(1)
.ok_or(DecodeError::RecursionLimitExceeded)?;
match tag.wire_type() {
WireType::LengthDelimited => {
let len = decode_varint(buf)?;
let len = usize::try_from(len).map_err(|_| DecodeError::MessageTooLarge)?;
if buf.remaining() < len {
return Err(DecodeError::UnexpectedEof);
}
let mut sub = buf.copy_to_bytes(len);
nested.merge_buf(&mut sub, depth)?;
}
WireType::StartGroup => {
nested.merge_group(buf, tag.field_number(), depth)?;
}
_ => {
return Err(DecodeError::WireTypeMismatch {
field_number: tag.field_number(),
expected: WireType::LengthDelimited as u8,
actual: tag.wire_type() as u8,
})
}
}
Ok(Value::Message(nested))
}
}
}
pub fn encode(&self, buf: &mut impl BufMut) {
for (&number, value) in &self.fields {
if let Some(fd) = self.field_or_extension(number) {
if should_skip_on_encode(fd, value) {
continue;
}
encode_field(fd, value, buf);
}
}
self.unknown.write_to(buf);
}
#[must_use]
pub fn encode_to_vec(&self) -> Vec<u8> {
let mut buf = Vec::with_capacity(self.encoded_len());
self.encode(&mut buf);
buf
}
#[must_use]
pub fn encoded_len(&self) -> usize {
let mut len = self.unknown.encoded_len();
for (&number, value) in &self.fields {
if let Some(fd) = self.field_or_extension(number) {
if should_skip_on_encode(fd, value) {
continue;
}
len += encoded_field_len(fd, value);
}
}
len
}
#[must_use]
pub fn from_message<M: Message>(
msg: &M,
pool: Arc<DescriptorPool>,
msg_idx: MessageIndex,
) -> Self {
let bytes = msg.encode_to_vec();
Self::decode(pool, msg_idx, &bytes)
.expect("generated message must round-trip through its own descriptor")
}
pub fn to_message<M: Message + Default>(&self) -> Result<M, DecodeError> {
let bytes = self.encode_to_vec();
let mut m = M::default();
m.merge_from_slice(&bytes)?;
Ok(m)
}
#[must_use]
pub fn field_by_number(&self, number: u32) -> Option<&Value> {
self.fields.get(&number)
}
#[must_use]
pub fn field_by_number_mut(&mut self, number: u32) -> Option<&mut Value> {
self.fields.get_mut(&number)
}
#[must_use]
pub fn field_mut(&mut self, field: &FieldDescriptor) -> Option<&mut Value> {
debug_assert!(
self.field_or_extension(field.number)
.is_some_and(|f| core::ptr::eq(f, field)),
"FieldDescriptor passed to field_mut() is not a member of {}",
self.message_descriptor().full_name,
);
self.fields.get_mut(&field.number)
}
#[cfg_attr(not(feature = "json"), allow(dead_code))]
pub(crate) fn insert_value(&mut self, number: u32, v: Value) {
self.fields.insert(number, v);
}
#[must_use]
pub fn unknown_fields(&self) -> &UnknownFields {
&self.unknown
}
pub fn unpack_any(&self) -> Result<DynamicMessage, AnyError> {
if self.message_descriptor().full_name != ANY_FULL_NAME {
return Err(AnyError::NotAny {
full_name: self.message_descriptor().full_name.clone(),
});
}
let type_url = match self.field_by_number(1) {
Some(Value::String(u)) if !u.is_empty() => u.as_str(),
_ => return Err(AnyError::MissingTypeUrl),
};
let value: &[u8] = match self.field_by_number(2) {
Some(Value::Bytes(b)) => b,
_ => &[],
};
let type_name = type_url.rsplit('/').next().unwrap_or(type_url);
let idx = self
.pool
.message_index(type_name)
.ok_or_else(|| AnyError::UnknownType {
type_url: type_url.to_owned(),
})?;
DynamicMessage::decode(Arc::clone(&self.pool), idx, value).map_err(|source| {
AnyError::Decode {
type_url: type_url.to_owned(),
source,
}
})
}
pub fn pack_any(&self) -> Result<DynamicMessage, AnyError> {
let any_idx = self
.pool
.message_index(ANY_FULL_NAME)
.ok_or(AnyError::AnyNotRegistered)?;
let type_url = alloc::format!(
"type.googleapis.com/{}",
self.message_descriptor().full_name
);
let mut any = DynamicMessage::new(Arc::clone(&self.pool), any_idx);
any.insert_value(1, Value::String(type_url));
any.insert_value(2, Value::Bytes(self.encode_to_vec()));
Ok(any)
}
#[must_use]
pub fn from_options<O>(pool: Arc<DescriptorPool>, options: &O) -> Option<Self>
where
O: Message + buffa::MessageName,
{
let idx = pool.message_index(O::FULL_NAME)?;
Self::decode(pool, idx, &options.encode_to_vec()).ok()
}
}
const ANY_FULL_NAME: &str = "google.protobuf.Any";
#[derive(Clone, Debug)]
#[non_exhaustive]
pub enum AnyError {
NotAny {
full_name: String,
},
AnyNotRegistered,
MissingTypeUrl,
UnknownType {
type_url: String,
},
Decode {
type_url: String,
source: DecodeError,
},
}
impl core::fmt::Display for AnyError {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
match self {
Self::NotAny { full_name } => {
write!(f, "not a google.protobuf.Any: {full_name}")
}
Self::AnyNotRegistered => {
write!(f, "google.protobuf.Any is not registered in the pool")
}
Self::MissingTypeUrl => write!(f, "Any has no type_url"),
Self::UnknownType { type_url } => {
write!(f, "Any type_url {type_url:?} not registered in the pool")
}
Self::Decode { type_url, source } => {
write!(f, "Any value for {type_url:?} failed to decode: {source}")
}
}
}
}
#[cfg(feature = "std")]
impl std::error::Error for AnyError {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
match self {
Self::Decode { source, .. } => Some(source),
_ => None,
}
}
}
impl ReflectMessage for DynamicMessage {
fn message_descriptor(&self) -> &MessageDescriptor {
self.pool.message(self.msg_idx)
}
fn pool(&self) -> &Arc<DescriptorPool> {
&self.pool
}
fn get(&self, field: &FieldDescriptor) -> ValueRef<'_> {
debug_assert!(
self.field_or_extension(field.number)
.is_some_and(|f| core::ptr::eq(f, field)),
"FieldDescriptor passed to get() is not a member of {}",
self.message_descriptor().full_name,
);
match self.fields.get(&field.number) {
Some(v) => v.as_ref(),
None => default_value_ref(field.kind, &self.pool),
}
}
fn has(&self, field: &FieldDescriptor) -> bool {
match self.fields.get(&field.number) {
None => false,
Some(Value::List(l)) => !l.is_empty(),
Some(Value::Map(m)) => !m.is_empty(),
Some(v) if field.presence == buffa::editions::FieldPresence::Implicit => {
!is_default_scalar(v)
}
Some(_) => true,
}
}
fn for_each_set(&self, f: &mut dyn FnMut(&FieldDescriptor, ValueRef<'_>)) {
for (&number, value) in &self.fields {
if let Some(fd) = self.field_or_extension(number) {
if !self.has(fd) {
continue;
}
f(fd, value.as_ref());
}
}
}
fn unknown_fields(&self) -> &buffa::UnknownFields {
&self.unknown
}
fn to_dynamic(&self) -> DynamicMessage {
self.clone()
}
}
impl ReflectMessageMut for DynamicMessage {
fn set(&mut self, field: &FieldDescriptor, value: Value) {
if let Some(oi) = field.oneof_index {
self.clear_other_oneof_members(oi, field.number);
}
self.fields.insert(field.number, value);
}
fn clear(&mut self, field: &FieldDescriptor) {
self.fields.remove(&field.number);
}
}
fn should_skip_on_encode(fd: &FieldDescriptor, value: &Value) -> bool {
if fd.presence != buffa::editions::FieldPresence::Implicit {
return false;
}
match (&fd.kind, value) {
(FieldKind::Singular(SingularKind::Scalar(_) | SingularKind::Enum(_)), v) => {
is_default_scalar(v)
}
_ => false,
}
}
fn is_default_scalar(v: &Value) -> bool {
match v {
Value::Bool(b) => !b,
Value::I32(n) => *n == 0,
Value::I64(n) => *n == 0,
Value::U32(n) => *n == 0,
Value::U64(n) => *n == 0,
Value::F32(f) => f.to_bits() == 0,
Value::F64(f) => f.to_bits() == 0,
Value::String(s) => s.is_empty(),
Value::Bytes(b) => b.is_empty(),
Value::EnumNumber(n) => *n == 0,
Value::Message(_) | Value::List(_) | Value::Map(_) => false,
}
}
fn is_packable(kind: SingularKind) -> bool {
match kind {
SingularKind::Scalar(s) => !matches!(s, ScalarType::String | ScalarType::Bytes),
SingularKind::Enum(_) => true,
SingularKind::Message(_) => false,
}
}
fn decode_scalar(s: ScalarType, wt: WireType, buf: &mut impl Buf) -> Result<Value, DecodeError> {
let _ = wt; Ok(match s {
ScalarType::Double => Value::F64(decode_double(buf)?),
ScalarType::Float => Value::F32(decode_float(buf)?),
ScalarType::Int64 => Value::I64(decode_int64(buf)?),
ScalarType::Uint64 => Value::U64(decode_uint64(buf)?),
ScalarType::Int32 => Value::I32(decode_int32(buf)?),
ScalarType::Fixed64 => Value::U64(decode_fixed64(buf)?),
ScalarType::Fixed32 => Value::U32(decode_fixed32(buf)?),
ScalarType::Bool => Value::Bool(decode_bool(buf)?),
ScalarType::String => Value::String(buffa::types::decode_string(buf)?),
ScalarType::Bytes => Value::Bytes(buffa::types::decode_bytes(buf)?),
ScalarType::Uint32 => Value::U32(decode_uint32(buf)?),
ScalarType::Sfixed32 => Value::I32(decode_sfixed32(buf)?),
ScalarType::Sfixed64 => Value::I64(decode_sfixed64(buf)?),
ScalarType::Sint32 => Value::I32(decode_sint32(buf)?),
ScalarType::Sint64 => Value::I64(decode_sint64(buf)?),
})
}
fn decode_packed_element(
kind: SingularKind,
field_number: u32,
buf: &mut impl Buf,
) -> Result<Value, DecodeError> {
match kind {
SingularKind::Scalar(s) => decode_scalar(s, WireType::Varint, buf),
SingularKind::Enum(_) => Ok(Value::EnumNumber(decode_int32(buf)?)),
SingularKind::Message(_) => Err(DecodeError::WireTypeMismatch {
field_number,
expected: WireType::Varint as u8,
actual: WireType::LengthDelimited as u8,
}),
}
}
fn decode_map_key(s: ScalarType, tag: Tag, buf: &mut impl Buf) -> Result<MapKey, DecodeError> {
Ok(match s {
ScalarType::Bool => MapKey::Bool(decode_bool(buf)?),
ScalarType::Int32 => MapKey::I32(decode_int32(buf)?),
ScalarType::Sint32 => MapKey::I32(decode_sint32(buf)?),
ScalarType::Sfixed32 => MapKey::I32(decode_sfixed32(buf)?),
ScalarType::Int64 => MapKey::I64(decode_int64(buf)?),
ScalarType::Sint64 => MapKey::I64(decode_sint64(buf)?),
ScalarType::Sfixed64 => MapKey::I64(decode_sfixed64(buf)?),
ScalarType::Uint32 => MapKey::U32(decode_uint32(buf)?),
ScalarType::Fixed32 => MapKey::U32(decode_fixed32(buf)?),
ScalarType::Uint64 => MapKey::U64(decode_uint64(buf)?),
ScalarType::Fixed64 => MapKey::U64(decode_fixed64(buf)?),
ScalarType::String => MapKey::String(buffa::types::decode_string(buf)?),
ScalarType::Double | ScalarType::Float | ScalarType::Bytes => {
return Err(DecodeError::WireTypeMismatch {
field_number: tag.field_number(),
expected: WireType::Varint as u8,
actual: tag.wire_type() as u8,
});
}
})
}
fn default_map_key(s: ScalarType) -> MapKey {
match s {
ScalarType::Bool => MapKey::Bool(false),
ScalarType::Int32 | ScalarType::Sint32 | ScalarType::Sfixed32 => MapKey::I32(0),
ScalarType::Int64 | ScalarType::Sint64 | ScalarType::Sfixed64 => MapKey::I64(0),
ScalarType::Uint32 | ScalarType::Fixed32 => MapKey::U32(0),
ScalarType::Uint64 | ScalarType::Fixed64 => MapKey::U64(0),
ScalarType::String => MapKey::String(String::new()),
ScalarType::Double | ScalarType::Float | ScalarType::Bytes => MapKey::Bool(false),
}
}
fn default_value(kind: SingularKind, pool: &Arc<DescriptorPool>) -> Value {
match kind {
SingularKind::Scalar(s) => default_scalar_value(s),
SingularKind::Enum(_) => Value::EnumNumber(0),
SingularKind::Message(midx) => Value::Message(DynamicMessage::new(Arc::clone(pool), midx)),
}
}
pub(super) fn default_scalar_value(s: ScalarType) -> Value {
match s {
ScalarType::Double => Value::F64(0.0),
ScalarType::Float => Value::F32(0.0),
ScalarType::Int64 | ScalarType::Sfixed64 | ScalarType::Sint64 => Value::I64(0),
ScalarType::Uint64 | ScalarType::Fixed64 => Value::U64(0),
ScalarType::Int32 | ScalarType::Sfixed32 | ScalarType::Sint32 => Value::I32(0),
ScalarType::Uint32 | ScalarType::Fixed32 => Value::U32(0),
ScalarType::Bool => Value::Bool(false),
ScalarType::String => Value::String(String::new()),
ScalarType::Bytes => Value::Bytes(Vec::new()),
}
}
fn default_value_ref(kind: FieldKind, pool: &Arc<DescriptorPool>) -> ValueRef<'static> {
static EMPTY_LIST: Vec<Value> = Vec::new();
static EMPTY_MAP: MapValue = MapValue::new();
match kind {
FieldKind::Singular(SingularKind::Scalar(s)) => default_scalar_ref(s),
FieldKind::Singular(SingularKind::Enum(_)) => ValueRef::EnumNumber(0),
FieldKind::Singular(SingularKind::Message(midx)) => ValueRef::Message(ReflectCow::Owned(
alloc::boxed::Box::new(DynamicMessage::new(Arc::clone(pool), midx)),
)),
FieldKind::List(_) => ValueRef::List(&EMPTY_LIST),
FieldKind::Map { .. } => ValueRef::Map(&EMPTY_MAP),
}
}
fn default_scalar_ref(s: ScalarType) -> ValueRef<'static> {
match s {
ScalarType::Double => ValueRef::F64(0.0),
ScalarType::Float => ValueRef::F32(0.0),
ScalarType::Int64 | ScalarType::Sfixed64 | ScalarType::Sint64 => ValueRef::I64(0),
ScalarType::Uint64 | ScalarType::Fixed64 => ValueRef::U64(0),
ScalarType::Int32 | ScalarType::Sfixed32 | ScalarType::Sint32 => ValueRef::I32(0),
ScalarType::Uint32 | ScalarType::Fixed32 => ValueRef::U32(0),
ScalarType::Bool => ValueRef::Bool(false),
ScalarType::String => ValueRef::String(""),
ScalarType::Bytes => ValueRef::Bytes(&[]),
}
}
fn encode_field(fd: &FieldDescriptor, value: &Value, buf: &mut impl BufMut) {
match (&fd.kind, value) {
(FieldKind::Singular(sk), v) => {
encode_singular_with_tag(fd.number, *sk, fd.delimited, v, buf);
}
(FieldKind::List(sk), Value::List(items)) => {
if items.is_empty() {
return;
}
if fd.packed && is_packable(*sk) {
Tag::new(fd.number, WireType::LengthDelimited).encode(buf);
let payload_len: usize = items.iter().map(|i| packed_element_len(*sk, i)).sum();
encode_varint(payload_len as u64, buf);
for item in items {
encode_packed_element(*sk, item, buf);
}
} else {
for item in items {
encode_singular_with_tag(fd.number, *sk, fd.delimited, item, buf);
}
}
}
(FieldKind::Map { key, value: vk }, Value::Map(m)) => {
for (k, v) in m {
Tag::new(fd.number, WireType::LengthDelimited).encode(buf);
let entry_len = map_key_len(*key, k)
+ 1 + map_value_len(*vk, v)
+ 1; encode_varint(entry_len as u64, buf);
Tag::new(1, map_key_wire_type(*key)).encode(buf);
encode_map_key(*key, k, buf);
Tag::new(2, singular_wire_type(*vk, false)).encode(buf);
encode_packed_element(*vk, v, buf); }
}
_ => {
}
}
}
fn encoded_field_len(fd: &FieldDescriptor, value: &Value) -> usize {
match (&fd.kind, value) {
(FieldKind::Singular(sk), v) => singular_len_with_tag(fd.number, *sk, fd.delimited, v),
(FieldKind::List(sk), Value::List(items)) => {
if items.is_empty() {
return 0;
}
if fd.packed && is_packable(*sk) {
let payload: usize = items.iter().map(|i| packed_element_len(*sk, i)).sum();
tag_len(fd.number, WireType::LengthDelimited)
+ uint64_encoded_len(payload as u64)
+ payload
} else {
items
.iter()
.map(|i| singular_len_with_tag(fd.number, *sk, fd.delimited, i))
.sum()
}
}
(FieldKind::Map { key, value: vk }, Value::Map(m)) => m
.iter()
.map(|(k, v)| {
let entry_len = 1 + map_key_len(*key, k) + 1 + map_value_len(*vk, v);
tag_len(fd.number, WireType::LengthDelimited)
+ uint64_encoded_len(entry_len as u64)
+ entry_len
})
.sum(),
_ => 0,
}
}
fn singular_wire_type(kind: SingularKind, delimited: bool) -> WireType {
match kind {
SingularKind::Scalar(s) => match s {
ScalarType::Double | ScalarType::Fixed64 | ScalarType::Sfixed64 => WireType::Fixed64,
ScalarType::Float | ScalarType::Fixed32 | ScalarType::Sfixed32 => WireType::Fixed32,
ScalarType::String | ScalarType::Bytes => WireType::LengthDelimited,
_ => WireType::Varint,
},
SingularKind::Enum(_) => WireType::Varint,
SingularKind::Message(_) => {
if delimited {
WireType::StartGroup
} else {
WireType::LengthDelimited
}
}
}
}
fn wire_type_compatible(kind: FieldKind, actual: WireType, delimited: bool) -> bool {
match kind {
FieldKind::Singular(SingularKind::Message(_)) => {
let _ = delimited;
matches!(actual, WireType::LengthDelimited | WireType::StartGroup)
}
FieldKind::Singular(sk) => actual == singular_wire_type(sk, false),
FieldKind::List(SingularKind::Message(_)) => {
matches!(actual, WireType::LengthDelimited | WireType::StartGroup)
}
FieldKind::List(sk) => {
actual == WireType::LengthDelimited || actual == singular_wire_type(sk, false)
}
FieldKind::Map { .. } => actual == WireType::LengthDelimited,
}
}
fn encode_singular_with_tag(
number: u32,
kind: SingularKind,
delimited: bool,
value: &Value,
buf: &mut impl BufMut,
) {
Tag::new(number, singular_wire_type(kind, delimited)).encode(buf);
match (kind, value) {
(SingularKind::Scalar(s), v) => encode_scalar(s, v, buf),
(SingularKind::Enum(_), Value::EnumNumber(n)) => encode_int32(*n, buf),
(SingularKind::Message(_), Value::Message(m)) => {
if delimited {
m.encode(buf);
Tag::new(number, WireType::EndGroup).encode(buf);
} else {
let len = m.encoded_len();
encode_varint(len as u64, buf);
m.encode(buf);
}
}
_ => {} }
}
fn singular_len_with_tag(number: u32, kind: SingularKind, delimited: bool, value: &Value) -> usize {
let tag_bytes = tag_len(number, singular_wire_type(kind, delimited));
let payload = match (kind, value) {
(SingularKind::Scalar(s), v) => scalar_len(s, v),
(SingularKind::Enum(_), Value::EnumNumber(n)) => int32_encoded_len(*n),
(SingularKind::Message(_), Value::Message(m)) => {
if delimited {
m.encoded_len() + tag_len(number, WireType::EndGroup)
} else {
let inner = m.encoded_len();
uint64_encoded_len(inner as u64) + inner
}
}
_ => 0,
};
tag_bytes + payload
}
fn encode_scalar(s: ScalarType, v: &Value, buf: &mut impl BufMut) {
match (s, v) {
(ScalarType::Double, Value::F64(x)) => encode_double(*x, buf),
(ScalarType::Float, Value::F32(x)) => encode_float(*x, buf),
(ScalarType::Int64, Value::I64(x)) => encode_int64(*x, buf),
(ScalarType::Uint64, Value::U64(x)) => encode_uint64(*x, buf),
(ScalarType::Int32, Value::I32(x)) => encode_int32(*x, buf),
(ScalarType::Fixed64, Value::U64(x)) => encode_fixed64(*x, buf),
(ScalarType::Fixed32, Value::U32(x)) => encode_fixed32(*x, buf),
(ScalarType::Bool, Value::Bool(x)) => encode_bool(*x, buf),
(ScalarType::String, Value::String(x)) => buffa::types::encode_string(x, buf),
(ScalarType::Bytes, Value::Bytes(x)) => buffa::types::encode_bytes(x, buf),
(ScalarType::Uint32, Value::U32(x)) => encode_uint32(*x, buf),
(ScalarType::Sfixed32, Value::I32(x)) => encode_sfixed32(*x, buf),
(ScalarType::Sfixed64, Value::I64(x)) => encode_sfixed64(*x, buf),
(ScalarType::Sint32, Value::I32(x)) => encode_sint32(*x, buf),
(ScalarType::Sint64, Value::I64(x)) => encode_sint64(*x, buf),
_ => {}
}
}
fn scalar_len(s: ScalarType, v: &Value) -> usize {
match (s, v) {
(ScalarType::Double | ScalarType::Fixed64 | ScalarType::Sfixed64, _) => 8,
(ScalarType::Float | ScalarType::Fixed32 | ScalarType::Sfixed32, _) => 4,
(ScalarType::Bool, Value::Bool(_)) => buffa::types::BOOL_ENCODED_LEN,
(ScalarType::Int64, Value::I64(x)) => int64_encoded_len(*x),
(ScalarType::Uint64, Value::U64(x)) => uint64_encoded_len(*x),
(ScalarType::Int32, Value::I32(x)) => int32_encoded_len(*x),
(ScalarType::Uint32, Value::U32(x)) => uint32_encoded_len(*x),
(ScalarType::Sint32, Value::I32(x)) => sint32_encoded_len(*x),
(ScalarType::Sint64, Value::I64(x)) => sint64_encoded_len(*x),
(ScalarType::String, Value::String(x)) => uint64_encoded_len(x.len() as u64) + x.len(),
(ScalarType::Bytes, Value::Bytes(x)) => uint64_encoded_len(x.len() as u64) + x.len(),
_ => 0,
}
}
fn encode_packed_element(kind: SingularKind, v: &Value, buf: &mut impl BufMut) {
match (kind, v) {
(SingularKind::Scalar(s), v) => encode_scalar(s, v, buf),
(SingularKind::Enum(_), Value::EnumNumber(n)) => encode_int32(*n, buf),
(SingularKind::Message(_), Value::Message(m)) => {
let len = m.encoded_len();
encode_varint(len as u64, buf);
m.encode(buf);
}
_ => {}
}
}
fn packed_element_len(kind: SingularKind, v: &Value) -> usize {
match (kind, v) {
(SingularKind::Scalar(s), v) => scalar_len(s, v),
(SingularKind::Enum(_), Value::EnumNumber(n)) => int32_encoded_len(*n),
(SingularKind::Message(_), Value::Message(m)) => {
let inner = m.encoded_len();
uint64_encoded_len(inner as u64) + inner
}
_ => 0,
}
}
fn map_value_len(kind: SingularKind, v: &Value) -> usize {
packed_element_len(kind, v)
}
fn map_key_wire_type(s: ScalarType) -> WireType {
match s {
ScalarType::Fixed32 | ScalarType::Sfixed32 => WireType::Fixed32,
ScalarType::Fixed64 | ScalarType::Sfixed64 => WireType::Fixed64,
ScalarType::String => WireType::LengthDelimited,
_ => WireType::Varint,
}
}
fn encode_map_key(s: ScalarType, k: &MapKey, buf: &mut impl BufMut) {
match (s, k) {
(ScalarType::Bool, MapKey::Bool(x)) => encode_bool(*x, buf),
(ScalarType::Int32, MapKey::I32(x)) => encode_int32(*x, buf),
(ScalarType::Sint32, MapKey::I32(x)) => encode_sint32(*x, buf),
(ScalarType::Sfixed32, MapKey::I32(x)) => encode_sfixed32(*x, buf),
(ScalarType::Int64, MapKey::I64(x)) => encode_int64(*x, buf),
(ScalarType::Sint64, MapKey::I64(x)) => encode_sint64(*x, buf),
(ScalarType::Sfixed64, MapKey::I64(x)) => encode_sfixed64(*x, buf),
(ScalarType::Uint32, MapKey::U32(x)) => encode_uint32(*x, buf),
(ScalarType::Fixed32, MapKey::U32(x)) => encode_fixed32(*x, buf),
(ScalarType::Uint64, MapKey::U64(x)) => encode_uint64(*x, buf),
(ScalarType::Fixed64, MapKey::U64(x)) => encode_fixed64(*x, buf),
(ScalarType::String, MapKey::String(x)) => buffa::types::encode_string(x, buf),
_ => {}
}
}
fn map_key_len(s: ScalarType, k: &MapKey) -> usize {
match (s, k) {
(ScalarType::Fixed32 | ScalarType::Sfixed32, _) => 4,
(ScalarType::Fixed64 | ScalarType::Sfixed64, _) => 8,
(ScalarType::Bool, MapKey::Bool(_)) => buffa::types::BOOL_ENCODED_LEN,
(ScalarType::Int32, MapKey::I32(x)) => int32_encoded_len(*x),
(ScalarType::Sint32, MapKey::I32(x)) => sint32_encoded_len(*x),
(ScalarType::Int64, MapKey::I64(x)) => int64_encoded_len(*x),
(ScalarType::Sint64, MapKey::I64(x)) => sint64_encoded_len(*x),
(ScalarType::Uint32, MapKey::U32(x)) => uint32_encoded_len(*x),
(ScalarType::Uint64, MapKey::U64(x)) => uint64_encoded_len(*x),
(ScalarType::String, MapKey::String(x)) => uint64_encoded_len(x.len() as u64) + x.len(),
_ => 0,
}
}
#[allow(dead_code)]
const _: fn(EnumIndex) = |_| {};
fn tag_len(field_number: u32, wt: WireType) -> usize {
uint64_encoded_len(((field_number as u64) << 3) | (wt as u64))
}