use crate::{ProtoAccessor, ProtoBuilder, Result, RotoError}; use std::str; /// The edition of the proto file. #[derive(Debug, Clone, Copy, PartialEq, Eq)] #[repr(i32)] pub enum Edition { EditionLegacy = 0, EditionProto2 = 1, EditionProto3 = 2, Edition2023 = 3, Edition2024 = 4, Edition2026 = 5, } impl Edition { pub fn from_i32(value: i32) -> Self { match value { 1 => Edition::EditionProto2, 2 => Edition::EditionProto3, 3 => Edition::Edition2023, 4 => Edition::Edition2024, 5 => Edition::Edition2026, _ => Edition::EditionLegacy, } } } pub struct FileDescriptorSet<'a>(ProtoAccessor<'a>); impl<'a> FileDescriptorSet<'a> { pub fn new(data: &'a [u8]) -> Result { Ok(Self(ProtoAccessor::new(data)?)) } pub fn file(&self) -> crate::RepeatedFieldIterator<'a> { self.0.iter_repeated(1) } } pub struct FileDescriptorProto<'a>(ProtoAccessor<'a>); impl<'a> FileDescriptorProto<'a> { pub fn new(data: &'a [u8]) -> Result { Ok(Self(ProtoAccessor::new(data)?)) } pub fn name(&self) -> Result<&'a str> { let (bytes, _) = self.0.get_value(1)?; str::from_utf8(bytes).map_err(|_| RotoError::WireFormatViolation) } pub fn package(&self) -> Result<&'a str> { let (bytes, _) = self.0.get_value(2)?; str::from_utf8(bytes).map_err(|_| RotoError::WireFormatViolation) } pub fn dependency(&self) -> crate::RepeatedFieldIterator<'a> { self.0.iter_repeated(3) } pub fn public_dependency(&self) -> crate::RepeatedFieldIterator<'a> { self.0.iter_repeated(10) } pub fn weak_dependency(&self) -> crate::RepeatedFieldIterator<'a> { self.0.iter_repeated(11) } pub fn option_dependency(&self) -> crate::RepeatedFieldIterator<'a> { self.0.iter_repeated(15) } pub fn message_type(&self) -> crate::RepeatedFieldIterator<'a> { self.0.iter_repeated(4) } pub fn enum_type(&self) -> crate::RepeatedFieldIterator<'a> { self.0.iter_repeated(5) } pub fn service(&self) -> crate::RepeatedFieldIterator<'a> { self.0.iter_repeated(6) } pub fn extension(&self) -> crate::RepeatedFieldIterator<'a> { self.0.iter_repeated(7) } pub fn syntax(&self) -> Result<&'a str> { let (bytes, _) = self.0.get_value(12)?; str::from_utf8(bytes).map_err(|_| RotoError::WireFormatViolation) } pub fn edition(&self) -> Result { let (bytes, _) = self.0.get_value(14)?; let (val, _) = crate::read_varint(bytes)?; Ok(Edition::from_i32(val as i32)) } pub fn builder(buf: &mut [u8]) -> FileDescriptorProtoBuilder<'_> { FileDescriptorProtoBuilder { builder: ProtoBuilder::new(buf), } } } pub struct FileDescriptorProtoBuilder<'b> { builder: ProtoBuilder<'b>, } impl<'b> FileDescriptorProtoBuilder<'b> { pub fn name(mut self, value: &str) -> Result { self.builder.write_string(1, value)?; Ok(self) } pub fn package(mut self, value: &str) -> Result { self.builder.write_string(2, value)?; Ok(self) } pub fn add_dependency(mut self, value: &str) -> Result { self.builder.write_string(3, value)?; Ok(self) } pub fn add_public_dependency(mut self, value: i32) -> Result { self.builder.write_int32(10, value)?; Ok(self) } pub fn add_weak_dependency(mut self, value: i32) -> Result { self.builder.write_int32(11, value)?; Ok(self) } pub fn add_option_dependency(mut self, value: &str) -> Result { self.builder.write_string(15, value)?; Ok(self) } pub fn add_message_type(mut self, data: &[u8]) -> Result { self.builder.write_bytes(4, data)?; Ok(self) } pub fn add_enum_type(mut self, data: &[u8]) -> Result { self.builder.write_bytes(5, data)?; Ok(self) } pub fn add_service(mut self, data: &[u8]) -> Result { self.builder.write_bytes(6, data)?; Ok(self) } pub fn add_extension(mut self, data: &[u8]) -> Result { self.builder.write_bytes(7, data)?; Ok(self) } pub fn syntax(mut self, value: &str) -> Result { self.builder.write_string(12, value)?; Ok(self) } pub fn edition(mut self, value: Edition) -> Result { self.builder.write_varint(14, value as u64)?; Ok(self) } pub fn finish(self) -> Result<&'b mut [u8]> { self.builder.finish() } } pub struct DescriptorProto<'a>(ProtoAccessor<'a>); impl<'a> DescriptorProto<'a> { pub fn new(data: &'a [u8]) -> Result { Ok(Self(ProtoAccessor::new(data)?)) } pub fn name(&self) -> Result<&'a str> { let (bytes, _) = self.0.get_value(1)?; str::from_utf8(bytes).map_err(|_| RotoError::WireFormatViolation) } pub fn field(&self) -> crate::RepeatedFieldIterator<'a> { self.0.iter_repeated(2) } pub fn extension(&self) -> crate::RepeatedFieldIterator<'a> { self.0.iter_repeated(6) } pub fn nested_type(&self) -> crate::RepeatedFieldIterator<'a> { self.0.iter_repeated(3) } pub fn enum_type(&self) -> crate::RepeatedFieldIterator<'a> { self.0.iter_repeated(4) } pub fn reserved_name(&self) -> crate::RepeatedFieldIterator<'a> { self.0.iter_repeated(10) } pub fn builder(buf: &mut [u8]) -> DescriptorProtoBuilder<'_> { DescriptorProtoBuilder { builder: ProtoBuilder::new(buf), } } } pub struct DescriptorProtoBuilder<'b> { builder: ProtoBuilder<'b>, } impl<'b> DescriptorProtoBuilder<'b> { pub fn name(mut self, value: &str) -> Result { self.builder.write_string(1, value)?; Ok(self) } pub fn add_field(mut self, data: &[u8]) -> Result { self.builder.write_bytes(2, data)?; Ok(self) } pub fn add_extension(mut self, data: &[u8]) -> Result { self.builder.write_bytes(6, data)?; Ok(self) } pub fn add_nested_type(mut self, data: &[u8]) -> Result { self.builder.write_bytes(3, data)?; Ok(self) } pub fn add_enum_type(mut self, data: &[u8]) -> Result { self.builder.write_bytes(4, data)?; Ok(self) } pub fn add_reserved_name(mut self, value: &str) -> Result { self.builder.write_string(10, value)?; Ok(self) } pub fn finish(self) -> Result<&'b mut [u8]> { self.builder.finish() } } pub struct EnumDescriptorProto<'a>(ProtoAccessor<'a>); impl<'a> EnumDescriptorProto<'a> { pub fn new(data: &'a [u8]) -> Result { Ok(Self(ProtoAccessor::new(data)?)) } pub fn name(&self) -> Result<&'a str> { let (bytes, _) = self.0.get_value(1)?; str::from_utf8(bytes).map_err(|_| RotoError::WireFormatViolation) } pub fn enum_value(&self) -> crate::RepeatedFieldIterator<'a> { self.0.iter_repeated(2) } pub fn reserved_value(&self) -> crate::RepeatedFieldIterator<'a> { self.0.iter_repeated(3) } pub fn options(&self) -> crate::RepeatedFieldIterator<'a> { self.0.iter_repeated(4) } pub fn builder(buf: &mut [u8]) -> EnumDescriptorProtoBuilder<'_> { EnumDescriptorProtoBuilder { builder: ProtoBuilder::new(buf), } } } pub struct EnumDescriptorProtoBuilder<'b> { builder: ProtoBuilder<'b>, } impl<'b> EnumDescriptorProtoBuilder<'b> { pub fn name(mut self, value: &str) -> Result { self.builder.write_string(1, value)?; Ok(self) } pub fn add_enum_value(mut self, data: &[u8]) -> Result { self.builder.write_bytes(2, data)?; Ok(self) } pub fn add_reserved_value(mut self, value: i32) -> Result { self.builder.write_int32(3, value)?; Ok(self) } pub fn add_options(mut self, data: &[u8]) -> Result { self.builder.write_bytes(4, data)?; Ok(self) } pub fn finish(self) -> Result<&'b mut [u8]> { self.builder.finish() } } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum FieldType { Double = 1, Float = 2, Int64 = 3, Uint64 = 4, Int32 = 5, Fixed64 = 6, Fixed32 = 7, Bool = 8, String = 9, Group = 10, Message = 11, Bytes = 12, Uint32 = 13, Enum = 14, Sfixed32 = 15, Sfixed64 = 16, Sint32 = 17, Sint64 = 18, } impl FieldType { pub fn from_i32(value: i32) -> Self { match value { 1 => FieldType::Double, 2 => FieldType::Float, 3 => FieldType::Int64, 4 => FieldType::Uint64, 5 => FieldType::Int32, 6 => FieldType::Fixed64, 7 => FieldType::Fixed32, 8 => FieldType::Bool, 9 => FieldType::String, 10 => FieldType::Group, 11 => FieldType::Message, 12 => FieldType::Bytes, 13 => FieldType::Uint32, 14 => FieldType::Enum, 15 => FieldType::Sfixed32, 16 => FieldType::Sfixed64, 17 => FieldType::Sint32, 18 => FieldType::Sint64, _ => FieldType::Int32, } } } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum FieldLabel { Optional = 1, Required = 2, Repeated = 3, } impl FieldLabel { pub fn from_i32(value: i32) -> Self { match value { 1 => FieldLabel::Optional, 2 => FieldLabel::Required, 3 => FieldLabel::Repeated, _ => FieldLabel::Optional, } } } pub struct FieldDescriptorProto<'a>(ProtoAccessor<'a>); impl<'a> FieldDescriptorProto<'a> { pub fn new(data: &'a [u8]) -> Result { Ok(Self(ProtoAccessor::new(data)?)) } pub fn name(&self) -> Result<&'a str> { let (bytes, _) = self.0.get_value(1)?; str::from_utf8(bytes).map_err(|_| RotoError::WireFormatViolation) } pub fn number(&self) -> Result { let (bytes, _) = self.0.get_value(3)?; let (val, _) = crate::read_varint(bytes)?; Ok(val as i32) } pub fn label(&self) -> Result { let (bytes, _) = self.0.get_value(4)?; let (val, _) = crate::read_varint(bytes)?; Ok(FieldLabel::from_i32(val as i32)) } pub fn field_type(&self) -> Result { let (bytes, _) = self.0.get_value(5)?; let (val, _) = crate::read_varint(bytes)?; Ok(FieldType::from_i32(val as i32)) } pub fn type_name(&self) -> Result<&'a str> { let (bytes, _) = self.0.get_value(6)?; str::from_utf8(bytes).map_err(|_| RotoError::WireFormatViolation) } pub fn default_value(&self) -> Result<&'a str> { let (bytes, _) = self.0.get_value(7)?; str::from_utf8(bytes).map_err(|_| RotoError::WireFormatViolation) } pub fn oneof_index(&self) -> Result { let (bytes, _) = self.0.get_value(9)?; let (val, _) = crate::read_varint(bytes)?; Ok(val as i32) } pub fn json_name(&self) -> Result<&'a str> { let (bytes, _) = self.0.get_value(10)?; str::from_utf8(bytes).map_err(|_| RotoError::WireFormatViolation) } pub fn proto3_optional(&self) -> Result { let (bytes, _) = self.0.get_value(17)?; let (val, _) = crate::read_varint(bytes)?; Ok(val != 0) } pub fn builder(buf: &mut [u8]) -> FieldDescriptorProtoBuilder<'_> { FieldDescriptorProtoBuilder { builder: ProtoBuilder::new(buf), } } } pub struct FieldDescriptorProtoBuilder<'b> { builder: ProtoBuilder<'b>, } impl<'b> FieldDescriptorProtoBuilder<'b> { pub fn name(mut self, value: &str) -> Result { self.builder.write_string(1, value)?; Ok(self) } pub fn number(mut self, value: i32) -> Result { self.builder.write_int32(3, value)?; Ok(self) } pub fn label(mut self, value: FieldLabel) -> Result { self.builder.write_varint(4, value as u64)?; Ok(self) } pub fn field_type(mut self, value: FieldType) -> Result { self.builder.write_varint(5, value as u64)?; Ok(self) } pub fn type_name(mut self, value: &str) -> Result { self.builder.write_string(6, value)?; Ok(self) } pub fn default_value(mut self, value: &str) -> Result { self.builder.write_string(7, value)?; Ok(self) } pub fn oneof_index(mut self, value: i32) -> Result { self.builder.write_int32(9, value)?; Ok(self) } pub fn json_name(mut self, value: &str) -> Result { self.builder.write_string(10, value)?; Ok(self) } pub fn proto3_optional(mut self, value: bool) -> Result { self.builder.write_varint(17, if value { 1 } else { 0 })?; Ok(self) } pub fn finish(self) -> Result<&'b mut [u8]> { self.builder.finish() } } pub struct GeneratedCodeInfo<'a>(ProtoAccessor<'a>); impl<'a> GeneratedCodeInfo<'a> { pub fn new(data: &'a [u8]) -> Result { Ok(Self(ProtoAccessor::new(data)?)) } pub fn annotation(&self) -> crate::RepeatedFieldIterator<'a> { self.0.iter_repeated(1) } pub fn builder(buf: &mut [u8]) -> GeneratedCodeInfoBuilder<'_> { GeneratedCodeInfoBuilder { builder: ProtoBuilder::new(buf), } } } pub struct GeneratedCodeInfoBuilder<'b> { builder: ProtoBuilder<'b>, } impl<'b> GeneratedCodeInfoBuilder<'b> { pub fn add_annotation(mut self, data: &[u8]) -> Result { self.builder.write_bytes(1, data)?; Ok(self) } pub fn finish(self) -> Result<&'b mut [u8]> { self.builder.finish() } } pub struct Version<'a>(ProtoAccessor<'a>); impl<'a> Version<'a> { pub fn new(data: &'a [u8]) -> Result { Ok(Self(ProtoAccessor::new(data)?)) } pub fn major(&self) -> Result { let (bytes, _) = self.0.get_value(1)?; let (val, _) = crate::read_varint(bytes)?; Ok(val as i32) } pub fn minor(&self) -> Result { let (bytes, _) = self.0.get_value(2)?; let (val, _) = crate::read_varint(bytes)?; Ok(val as i32) } pub fn patch(&self) -> Result { let (bytes, _) = self.0.get_value(3)?; let (val, _) = crate::read_varint(bytes)?; Ok(val as i32) } pub fn suffix(&self) -> Result<&'a str> { let (bytes, _) = self.0.get_value(4)?; str::from_utf8(bytes).map_err(|_| RotoError::WireFormatViolation) } pub fn builder(buf: &mut [u8]) -> VersionBuilder<'_> { VersionBuilder { builder: ProtoBuilder::new(buf), } } } pub struct VersionBuilder<'b> { builder: ProtoBuilder<'b>, } impl<'b> VersionBuilder<'b> { pub fn major(mut self, value: i32) -> Result { self.builder.write_int32(1, value)?; Ok(self) } pub fn minor(mut self, value: i32) -> Result { self.builder.write_int32(2, value)?; Ok(self) } pub fn patch(mut self, value: i32) -> Result { self.builder.write_int32(3, value)?; Ok(self) } pub fn suffix(mut self, value: &str) -> Result { self.builder.write_string(4, value)?; Ok(self) } pub fn finish(self) -> Result<&'b mut [u8]> { self.builder.finish() } } pub struct CodeGeneratorRequest<'a>(ProtoAccessor<'a>); impl<'a> CodeGeneratorRequest<'a> { pub fn new(data: &'a [u8]) -> Result { Ok(Self(ProtoAccessor::new(data)?)) } pub fn file_to_generate(&self) -> crate::RepeatedFieldIterator<'a> { self.0.iter_repeated(1) } pub fn parameter(&self) -> Result<&'a str> { let (bytes, _) = self.0.get_value(2)?; str::from_utf8(bytes).map_err(|_| RotoError::WireFormatViolation) } pub fn compiler_version(&self) -> Result<&'a [u8]> { let (bytes, _) = self.0.get_value(3)?; Ok(bytes) } pub fn proto_file(&self) -> crate::RepeatedFieldIterator<'a> { self.0.iter_repeated(15) } pub fn source_file_descriptors(&self) -> crate::RepeatedFieldIterator<'a> { self.0.iter_repeated(17) } pub fn builder(buf: &mut [u8]) -> CodeGeneratorRequestBuilder<'_> { CodeGeneratorRequestBuilder { builder: ProtoBuilder::new(buf), } } } pub struct CodeGeneratorRequestBuilder<'b> { builder: ProtoBuilder<'b>, } impl<'b> CodeGeneratorRequestBuilder<'b> { pub fn add_file_to_generate(mut self, value: &str) -> Result { self.builder.write_string(1, value)?; Ok(self) } pub fn parameter(mut self, value: &str) -> Result { self.builder.write_string(2, value)?; Ok(self) } pub fn compiler_version(mut self, data: &[u8]) -> Result { self.builder.write_bytes(3, data)?; Ok(self) } pub fn add_proto_file(mut self, data: &[u8]) -> Result { self.builder.write_bytes(15, data)?; Ok(self) } pub fn add_source_file_descriptor(mut self, data: &[u8]) -> Result { self.builder.write_bytes(17, data)?; Ok(self) } pub fn finish(self) -> Result<&'b mut [u8]> { self.builder.finish() } } pub struct CodeGeneratorResponse<'a>(ProtoAccessor<'a>); impl<'a> CodeGeneratorResponse<'a> { pub fn new(data: &'a [u8]) -> Result { Ok(Self(ProtoAccessor::new(data)?)) } pub fn error(&self) -> Result<&'a str> { let (bytes, _) = self.0.get_value(1)?; str::from_utf8(bytes).map_err(|_| RotoError::WireFormatViolation) } pub fn supported_features(&self) -> Result { let (bytes, _) = self.0.get_value(2)?; let (val, _) = crate::read_varint(bytes)?; Ok(val) } pub fn minimum_edition(&self) -> Result { let (bytes, _) = self.0.get_value(3)?; let (val, _) = crate::read_varint(bytes)?; Ok(val as i32) } pub fn maximum_edition(&self) -> Result { let (bytes, _) = self.0.get_value(4)?; let (val, _) = crate::read_varint(bytes)?; Ok(val as i32) } pub fn file(&self) -> crate::RepeatedFieldIterator<'a> { self.0.iter_repeated(15) } pub fn builder(buf: &mut [u8]) -> CodeGeneratorResponseBuilder<'_> { CodeGeneratorResponseBuilder { builder: ProtoBuilder::new(buf), } } } pub struct CodeGeneratorResponseBuilder<'b> { builder: ProtoBuilder<'b>, } impl<'b> CodeGeneratorResponseBuilder<'b> { pub fn error(mut self, value: &str) -> Result { self.builder.write_string(1, value)?; Ok(self) } pub fn supported_features(mut self, value: u64) -> Result { self.builder.write_varint(2, value)?; Ok(self) } pub fn minimum_edition(mut self, value: i32) -> Result { self.builder.write_int32(3, value)?; Ok(self) } pub fn maximum_edition(mut self, value: i32) -> Result { self.builder.write_int32(4, value)?; Ok(self) } pub fn add_file(mut self, data: &[u8]) -> Result { self.builder.write_bytes(15, data)?; Ok(self) } pub fn finish(self) -> Result<&'b mut [u8]> { self.builder.finish() } } pub struct ResponseFile<'a>(ProtoAccessor<'a>); impl<'a> ResponseFile<'a> { pub fn new(data: &'a [u8]) -> Result { Ok(Self(ProtoAccessor::new(data)?)) } pub fn name(&self) -> Result<&'a str> { let (bytes, _) = self.0.get_value(1)?; str::from_utf8(bytes).map_err(|_| RotoError::WireFormatViolation) } pub fn insertion_point(&self) -> Result<&'a str> { let (bytes, _) = self.0.get_value(2)?; str::from_utf8(bytes).map_err(|_| RotoError::WireFormatViolation) } pub fn content(&self) -> Result<&'a str> { let (bytes, _) = self.0.get_value(15)?; str::from_utf8(bytes).map_err(|_| RotoError::WireFormatViolation) } pub fn generated_code_info(&self) -> Result<&'a [u8]> { let (bytes, _) = self.0.get_value(16)?; Ok(bytes) } pub fn builder(buf: &mut [u8]) -> ResponseFileBuilder<'_> { ResponseFileBuilder { builder: ProtoBuilder::new(buf), } } } pub struct ResponseFileBuilder<'b> { builder: ProtoBuilder<'b>, } impl<'b> ResponseFileBuilder<'b> { pub fn name(mut self, value: &str) -> Result { self.builder.write_string(1, value)?; Ok(self) } pub fn insertion_point(mut self, value: &str) -> Result { self.builder.write_string(2, value)?; Ok(self) } pub fn content(mut self, value: &str) -> Result { self.builder.write_string(15, value)?; Ok(self) } pub fn generated_code_info(mut self, data: &[u8]) -> Result { self.builder.write_bytes(16, data)?; Ok(self) } pub fn finish(self) -> Result<&'b mut [u8]> { self.builder.finish() } } #[cfg(test)] mod tests { use super::*; use std::fs; #[test] fn test_read_descriptor_set() { let data = include_bytes!("../../../../data/test_types.desc"); let set = FileDescriptorSet::new(data).expect("Failed to parse FileDescriptorSet"); let mut files = set.file(); let (file_data, _) = files.next().expect("No file descriptors found").expect("Failed to read file descriptor"); let file_proto = FileDescriptorProto::new(file_data).expect("Failed to parse FileDescriptorProto"); assert_eq!(file_proto.name().unwrap(), "data/test_types.proto"); assert_eq!(file_proto.package().unwrap(), "roto.test"); } } pub struct Annotation<'a>(ProtoAccessor<'a>); impl<'a> Annotation<'a> { pub fn new(data: &'a [u8]) -> Result { Ok(Self(ProtoAccessor::new(data)?)) } pub fn path(&self) -> crate::RepeatedFieldIterator<'a> { self.0.iter_repeated(1) } pub fn source_file(&self) -> Result<&'a str> { let (bytes, _) = self.0.get_value(2)?; str::from_utf8(bytes).map_err(|_| RotoError::WireFormatViolation) } pub fn begin(&self) -> Result { let (bytes, _) = self.0.get_value(3)?; let (val, _) = crate::read_varint(bytes)?; Ok(val as i32) } pub fn end(&self) -> Result { let (bytes, _) = self.0.get_value(4)?; let (val, _) = crate::read_varint(bytes)?; Ok(val as i32) } pub fn semantic(&self) -> Result { let (bytes, _) = self.0.get_value(5)?; let (val, _) = crate::read_varint(bytes)?; Ok(val as i32) } pub fn builder(buf: &mut [u8]) -> AnnotationBuilder<'_> { AnnotationBuilder { builder: ProtoBuilder::new(buf), } } } pub struct AnnotationBuilder<'b> { builder: ProtoBuilder<'b>, } impl<'b> AnnotationBuilder<'b> { pub fn add_path(mut self, value: i32) -> Result { self.builder.write_int32(1, value)?; Ok(self) } pub fn source_file(mut self, value: &str) -> Result { self.builder.write_string(2, value)?; Ok(self) } pub fn begin(mut self, value: i32) -> Result { self.builder.write_int32(3, value)?; Ok(self) } pub fn end(mut self, value: i32) -> Result { self.builder.write_int32(4, value)?; Ok(self) } pub fn semantic(mut self, value: i32) -> Result { self.builder.write_varint(5, value as u64)?; Ok(self) } pub fn finish(self) -> Result<&'b mut [u8]> { self.builder.finish() } }