use std::any::Any;
use std::any::TypeId;
use std::default::Default;
use std::fmt;
use std::io::Read;
use std::io::Write;
use clear::Clear;
use reflect::MessageDescriptor;
use reflect::EnumDescriptor;
use reflect::EnumValueDescriptor;
use unknown::UnknownFields;
use stream::WithCodedInputStream;
use stream::WithCodedOutputStream;
use stream::CodedInputStream;
use stream::CodedOutputStream;
use stream::with_coded_output_stream_to_bytes;
use error::ProtobufResult;
pub trait MessageStatic : Message + Clone + Default + PartialEq {
fn new() -> Self;
fn descriptor_static(_: Option<Self>) -> &'static MessageDescriptor {
panic!("descriptor_static is not implemented for message, \
LITE_RUNTIME must be used");
}
}
pub trait Message : fmt::Debug + Clear + Any {
fn descriptor(&self) -> &'static MessageDescriptor;
fn is_initialized(&self) -> bool;
fn merge_from(&mut self, is: &mut CodedInputStream) -> ProtobufResult<()>;
fn write_to_with_cached_sizes(&self, os: &mut CodedOutputStream) -> ProtobufResult<()>;
fn compute_size(&self) -> u32;
fn get_cached_size(&self) -> u32;
fn write_to(&self, os: &mut CodedOutputStream) -> ProtobufResult<()> {
self.check_initialized();
self.compute_size();
try!(self.write_to_with_cached_sizes(os));
Ok(())
}
fn write_length_delimited_to(&self, os: &mut CodedOutputStream) -> ProtobufResult<()> {
let size = self.compute_size();
try!(os.write_raw_varint32(size));
try!(self.write_to_with_cached_sizes(os));
Ok(())
}
fn merge_from_bytes(&mut self, bytes: &[u8]) -> ProtobufResult<()> {
let mut is = CodedInputStream::from_bytes(bytes);
self.merge_from(&mut is)
}
fn check_initialized(&self) {
assert!(self.is_initialized());
}
fn write_to_writer(&self, w: &mut Write) -> ProtobufResult<()> {
w.with_coded_output_stream(|os| {
self.write_to(os)
})
}
fn write_to_vec(&self, v: &mut Vec<u8>) -> ProtobufResult<()> {
v.with_coded_output_stream(|os| {
self.write_to(os)
})
}
fn write_to_bytes(&self) -> ProtobufResult<Vec<u8>> {
let mut v = Vec::new();
try!(self.write_to_vec(&mut v));
Ok(v)
}
fn write_length_delimited_to_writer(&self, w: &mut Write) -> ProtobufResult<()> {
w.with_coded_output_stream(|os| {
self.write_length_delimited_to(os)
})
}
fn write_length_delimited_to_bytes(&self) -> ProtobufResult<Vec<u8>> {
with_coded_output_stream_to_bytes(|os| {
self.write_length_delimited_to(os)
})
}
fn get_unknown_fields<'s>(&'s self) -> &'s UnknownFields;
fn mut_unknown_fields<'s>(&'s mut self) -> &'s mut UnknownFields;
fn type_id(&self) -> TypeId;
fn as_any(&self) -> &Any;
}
pub fn message_is<M : Message>(m: &Message) -> bool {
TypeId::of::<M>() == m.type_id()
}
pub fn message_down_cast<'a, M : Message + 'a>(m: &'a Message) -> &'a M {
assert!(message_is::<M>(m));
m.as_any().downcast_ref::<M>().unwrap()
}
pub trait ProtobufEnum : Eq + Sized {
fn value(&self) -> i32;
fn from_i32(v: i32) -> Option<Self>;
fn values() -> &'static [Self] {
panic!();
}
fn descriptor(&self) -> &'static EnumValueDescriptor {
self.enum_descriptor().value_by_number(self.value())
}
fn enum_descriptor(&self) -> &'static EnumDescriptor {
ProtobufEnum::enum_descriptor_static(None::<Self>)
}
fn enum_descriptor_static(_: Option<Self>) -> &'static EnumDescriptor {
panic!();
}
}
pub fn parse_from<M : Message + MessageStatic>(is: &mut CodedInputStream) -> ProtobufResult<M> {
let mut r: M = MessageStatic::new();
try!(r.merge_from(is));
r.check_initialized();
Ok(r)
}
pub fn parse_from_reader<M : Message + MessageStatic>(reader: &mut Read) -> ProtobufResult<M> {
reader.with_coded_input_stream(|is| {
parse_from::<M>(is)
})
}
pub fn parse_from_bytes<M : Message + MessageStatic>(bytes: &[u8]) -> ProtobufResult<M> {
bytes.with_coded_input_stream(|is| {
parse_from::<M>(is)
})
}
pub fn parse_length_delimited_from<M : Message + MessageStatic>(is: &mut CodedInputStream)
-> ProtobufResult<M>
{
is.read_message::<M>()
}
pub fn parse_length_delimited_from_reader<M : Message + MessageStatic>(r: &mut Read) -> ProtobufResult<M> {
r.with_coded_input_stream(|is| {
is.read_message::<M>()
})
}
pub fn parse_length_delimited_from_bytes<M : Message + MessageStatic>(bytes: &[u8]) -> ProtobufResult<M> {
bytes.with_coded_input_stream(|is| {
is.read_message::<M>()
})
}