diff --git a/data/test_types.desc b/data/test_types.desc new file mode 100644 index 0000000..6ff3fb1 Binary files /dev/null and b/data/test_types.desc differ diff --git a/src/lib.rs b/src/lib.rs index 636c7c1..18ef69e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,3 +1,4 @@ +pub mod proto_gen; use std::fmt; #[derive(Debug, PartialEq, Eq)] @@ -180,7 +181,7 @@ impl<'a> ProtoAccessor<'a> { } /// Returns the value and wire type of the last occurrence of the specified field. - pub fn get_value(&self, field_number: u32) -> Result<(&[u8], WireType)> { + pub fn get_value(&self, field_number: u32) -> Result<(&'a [u8], WireType)> { let mut last_value = None; for item in self.fields() { let (tag, value) = item?; diff --git a/src/proto_gen/google/protobuf/compiler/plugin.rs b/src/proto_gen/google/protobuf/compiler/plugin.rs new file mode 100644 index 0000000..2b4dae9 --- /dev/null +++ b/src/proto_gen/google/protobuf/compiler/plugin.rs @@ -0,0 +1,281 @@ +use crate::{ProtoAccessor, ProtoBuilder, Result, RotoError}; +use crate::proto_gen::google::protobuf::descriptor::{FileDescriptorProto, GeneratedCodeInfo}; +use std::str; + +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> { + let (bytes, _) = self.0.get_value(3)?; + Version::new(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 CodeGeneratorResponseFile<'a>(ProtoAccessor<'a>); + +impl<'a> CodeGeneratorResponseFile<'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> { + let (bytes, _) = self.0.get_value(16)?; + GeneratedCodeInfo::new(bytes) + } + + pub fn builder(buf: &mut [u8]) -> CodeGeneratorResponseFileBuilder<'_> { + CodeGeneratorResponseFileBuilder { + builder: ProtoBuilder::new(buf), + } + } +} + +pub struct CodeGeneratorResponseFileBuilder<'b> { + builder: ProtoBuilder<'b>, +} + +impl<'b> CodeGeneratorResponseFileBuilder<'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() + } +} diff --git a/src/proto_gen/google/protobuf/descriptor.rs b/src/proto_gen/google/protobuf/descriptor.rs new file mode 100644 index 0000000..5598ae4 --- /dev/null +++ b/src/proto_gen/google/protobuf/descriptor.rs @@ -0,0 +1,566 @@ +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() + } +} + +#[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() + } +} + +#[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() + } +} diff --git a/src/proto_gen/mod.rs b/src/proto_gen/mod.rs new file mode 100644 index 0000000..b154821 --- /dev/null +++ b/src/proto_gen/mod.rs @@ -0,0 +1,8 @@ +pub mod google { + pub mod protobuf { + pub mod descriptor; + pub mod compiler { + pub mod plugin; + } + } +}