use buffa_descriptor::generated::descriptor::DescriptorProto;
use crate::{
field::FieldDescriptor,
file::FileDescriptor,
oneof::OneofDescriptor,
pool::{DescriptorPool, MessageIndex},
};
#[derive(Clone, Debug)]
pub struct MessageDescriptor {
pub(crate) pool: DescriptorPool,
pub(crate) index: MessageIndex,
}
impl MessageDescriptor {
#[must_use]
pub fn full_name(&self) -> &str {
&self.pool.inner.messages[self.index as usize].full_name
}
#[must_use]
pub fn name(&self) -> &str {
&self.pool.inner.messages[self.index as usize].name
}
#[must_use]
pub fn parent_file(&self) -> FileDescriptor {
let entry = &self.pool.inner.messages[self.index as usize];
FileDescriptor {
pool: self.pool.clone(),
index: entry.file,
}
}
#[must_use]
pub fn parent_message(&self) -> Option<MessageDescriptor> {
let entry = &self.pool.inner.messages[self.index as usize];
entry.parent.map(|idx| MessageDescriptor {
pool: self.pool.clone(),
index: idx,
})
}
pub fn fields(&self) -> impl ExactSizeIterator<Item = FieldDescriptor> + '_ {
let pool = self.pool.clone();
let owner = self.index;
let len = self.pool.inner.messages[owner as usize].fields.len() as u32;
(0..len).map(move |fi| FieldDescriptor {
pool: pool.clone(),
message: owner,
index: fi,
})
}
pub fn oneofs(&self) -> impl ExactSizeIterator<Item = OneofDescriptor> + '_ {
let pool = self.pool.clone();
let owner = self.index;
let len = self.pool.inner.messages[owner as usize].oneofs.len() as u32;
(0..len).map(move |oi| OneofDescriptor {
pool: pool.clone(),
message: owner,
index: oi,
})
}
#[must_use]
pub fn get_field_by_name(&self, name: &str) -> Option<FieldDescriptor> {
let entry = &self.pool.inner.messages[self.index as usize];
entry.by_name.get(name).map(|fi| FieldDescriptor {
pool: self.pool.clone(),
message: self.index,
index: *fi,
})
}
#[must_use]
pub fn get_field_by_json_name(&self, name: &str) -> Option<FieldDescriptor> {
let entry = &self.pool.inner.messages[self.index as usize];
entry.by_json_name.get(name).map(|fi| FieldDescriptor {
pool: self.pool.clone(),
message: self.index,
index: *fi,
})
}
#[must_use]
pub fn get_field_by_number(&self, number: u32) -> Option<FieldDescriptor> {
let entry = &self.pool.inner.messages[self.index as usize];
entry.by_number.get(&number).map(|fi| FieldDescriptor {
pool: self.pool.clone(),
message: self.index,
index: *fi,
})
}
#[must_use]
pub fn is_map_entry(&self) -> bool {
self.pool.inner.messages[self.index as usize].is_map_entry
}
#[must_use]
pub fn descriptor_proto(&self) -> &DescriptorProto {
let entry = &self.pool.inner.messages[self.index as usize];
let file = &self.pool.inner.files[entry.file as usize];
crate::pool_build::resolve_message_proto(&file.proto, &entry.proto_path)
}
}
impl PartialEq for MessageDescriptor {
fn eq(&self, other: &Self) -> bool {
std::sync::Arc::ptr_eq(&self.pool.inner, &other.pool.inner) && self.index == other.index
}
}
impl Eq for MessageDescriptor {}