Add protobuf descriptor and compiler plugin support
Implement accessors and builders for FileDescriptorSet, CodeGeneratorRequest, CodeGeneratorResponse, and related types.
This commit is contained in:
Binary file not shown.
+2
-1
@@ -1,3 +1,4 @@
|
|||||||
|
pub mod proto_gen;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq)]
|
#[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.
|
/// 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;
|
let mut last_value = None;
|
||||||
for item in self.fields() {
|
for item in self.fields() {
|
||||||
let (tag, value) = item?;
|
let (tag, value) = item?;
|
||||||
|
|||||||
@@ -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<Self> {
|
||||||
|
Ok(Self(ProtoAccessor::new(data)?))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn major(&self) -> Result<i32> {
|
||||||
|
let (bytes, _) = self.0.get_value(1)?;
|
||||||
|
let (val, _) = crate::read_varint(bytes)?;
|
||||||
|
Ok(val as i32)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn minor(&self) -> Result<i32> {
|
||||||
|
let (bytes, _) = self.0.get_value(2)?;
|
||||||
|
let (val, _) = crate::read_varint(bytes)?;
|
||||||
|
Ok(val as i32)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn patch(&self) -> Result<i32> {
|
||||||
|
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> {
|
||||||
|
self.builder.write_int32(1, value)?;
|
||||||
|
Ok(self)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn minor(mut self, value: i32) -> Result<Self> {
|
||||||
|
self.builder.write_int32(2, value)?;
|
||||||
|
Ok(self)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn patch(mut self, value: i32) -> Result<Self> {
|
||||||
|
self.builder.write_int32(3, value)?;
|
||||||
|
Ok(self)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn suffix(mut self, value: &str) -> Result<Self> {
|
||||||
|
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<Self> {
|
||||||
|
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<Version<'a>> {
|
||||||
|
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> {
|
||||||
|
self.builder.write_string(1, value)?;
|
||||||
|
Ok(self)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn parameter(mut self, value: &str) -> Result<Self> {
|
||||||
|
self.builder.write_string(2, value)?;
|
||||||
|
Ok(self)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn compiler_version(mut self, data: &[u8]) -> Result<Self> {
|
||||||
|
self.builder.write_bytes(3, data)?;
|
||||||
|
Ok(self)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn add_proto_file(mut self, data: &[u8]) -> Result<Self> {
|
||||||
|
self.builder.write_bytes(15, data)?;
|
||||||
|
Ok(self)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn add_source_file_descriptor(mut self, data: &[u8]) -> Result<Self> {
|
||||||
|
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<Self> {
|
||||||
|
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<u64> {
|
||||||
|
let (bytes, _) = self.0.get_value(2)?;
|
||||||
|
let (val, _) = crate::read_varint(bytes)?;
|
||||||
|
Ok(val)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn minimum_edition(&self) -> Result<i32> {
|
||||||
|
let (bytes, _) = self.0.get_value(3)?;
|
||||||
|
let (val, _) = crate::read_varint(bytes)?;
|
||||||
|
Ok(val as i32)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn maximum_edition(&self) -> Result<i32> {
|
||||||
|
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> {
|
||||||
|
self.builder.write_string(1, value)?;
|
||||||
|
Ok(self)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn supported_features(mut self, value: u64) -> Result<Self> {
|
||||||
|
self.builder.write_varint(2, value)?;
|
||||||
|
Ok(self)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn minimum_edition(mut self, value: i32) -> Result<Self> {
|
||||||
|
self.builder.write_int32(3, value)?;
|
||||||
|
Ok(self)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn maximum_edition(mut self, value: i32) -> Result<Self> {
|
||||||
|
self.builder.write_int32(4, value)?;
|
||||||
|
Ok(self)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn add_file(mut self, data: &[u8]) -> Result<Self> {
|
||||||
|
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<Self> {
|
||||||
|
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<GeneratedCodeInfo<'a>> {
|
||||||
|
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> {
|
||||||
|
self.builder.write_string(1, value)?;
|
||||||
|
Ok(self)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn insertion_point(mut self, value: &str) -> Result<Self> {
|
||||||
|
self.builder.write_string(2, value)?;
|
||||||
|
Ok(self)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn content(mut self, value: &str) -> Result<Self> {
|
||||||
|
self.builder.write_string(15, value)?;
|
||||||
|
Ok(self)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn generated_code_info(mut self, data: &[u8]) -> Result<Self> {
|
||||||
|
self.builder.write_bytes(16, data)?;
|
||||||
|
Ok(self)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn finish(self) -> Result<&'b mut [u8]> {
|
||||||
|
self.builder.finish()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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<Self> {
|
||||||
|
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<Self> {
|
||||||
|
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<Edition> {
|
||||||
|
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> {
|
||||||
|
self.builder.write_string(1, value)?;
|
||||||
|
Ok(self)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn package(mut self, value: &str) -> Result<Self> {
|
||||||
|
self.builder.write_string(2, value)?;
|
||||||
|
Ok(self)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn add_dependency(mut self, value: &str) -> Result<Self> {
|
||||||
|
self.builder.write_string(3, value)?;
|
||||||
|
Ok(self)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn add_public_dependency(mut self, value: i32) -> Result<Self> {
|
||||||
|
self.builder.write_int32(10, value)?;
|
||||||
|
Ok(self)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn add_weak_dependency(mut self, value: i32) -> Result<Self> {
|
||||||
|
self.builder.write_int32(11, value)?;
|
||||||
|
Ok(self)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn add_option_dependency(mut self, value: &str) -> Result<Self> {
|
||||||
|
self.builder.write_string(15, value)?;
|
||||||
|
Ok(self)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn add_message_type(mut self, data: &[u8]) -> Result<Self> {
|
||||||
|
self.builder.write_bytes(4, data)?;
|
||||||
|
Ok(self)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn add_enum_type(mut self, data: &[u8]) -> Result<Self> {
|
||||||
|
self.builder.write_bytes(5, data)?;
|
||||||
|
Ok(self)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn add_service(mut self, data: &[u8]) -> Result<Self> {
|
||||||
|
self.builder.write_bytes(6, data)?;
|
||||||
|
Ok(self)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn add_extension(mut self, data: &[u8]) -> Result<Self> {
|
||||||
|
self.builder.write_bytes(7, data)?;
|
||||||
|
Ok(self)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn syntax(mut self, value: &str) -> Result<Self> {
|
||||||
|
self.builder.write_string(12, value)?;
|
||||||
|
Ok(self)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn edition(mut self, value: Edition) -> Result<Self> {
|
||||||
|
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<Self> {
|
||||||
|
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> {
|
||||||
|
self.builder.write_string(1, value)?;
|
||||||
|
Ok(self)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn add_field(mut self, data: &[u8]) -> Result<Self> {
|
||||||
|
self.builder.write_bytes(2, data)?;
|
||||||
|
Ok(self)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn add_extension(mut self, data: &[u8]) -> Result<Self> {
|
||||||
|
self.builder.write_bytes(6, data)?;
|
||||||
|
Ok(self)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn add_nested_type(mut self, data: &[u8]) -> Result<Self> {
|
||||||
|
self.builder.write_bytes(3, data)?;
|
||||||
|
Ok(self)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn add_enum_type(mut self, data: &[u8]) -> Result<Self> {
|
||||||
|
self.builder.write_bytes(4, data)?;
|
||||||
|
Ok(self)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn add_reserved_name(mut self, value: &str) -> Result<Self> {
|
||||||
|
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<Self> {
|
||||||
|
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<i32> {
|
||||||
|
let (bytes, _) = self.0.get_value(3)?;
|
||||||
|
let (val, _) = crate::read_varint(bytes)?;
|
||||||
|
Ok(val as i32)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn label(&self) -> Result<FieldLabel> {
|
||||||
|
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<FieldType> {
|
||||||
|
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<i32> {
|
||||||
|
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<bool> {
|
||||||
|
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> {
|
||||||
|
self.builder.write_string(1, value)?;
|
||||||
|
Ok(self)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn number(mut self, value: i32) -> Result<Self> {
|
||||||
|
self.builder.write_int32(3, value)?;
|
||||||
|
Ok(self)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn label(mut self, value: FieldLabel) -> Result<Self> {
|
||||||
|
self.builder.write_varint(4, value as u64)?;
|
||||||
|
Ok(self)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn field_type(mut self, value: FieldType) -> Result<Self> {
|
||||||
|
self.builder.write_varint(5, value as u64)?;
|
||||||
|
Ok(self)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn type_name(mut self, value: &str) -> Result<Self> {
|
||||||
|
self.builder.write_string(6, value)?;
|
||||||
|
Ok(self)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn default_value(mut self, value: &str) -> Result<Self> {
|
||||||
|
self.builder.write_string(7, value)?;
|
||||||
|
Ok(self)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn oneof_index(mut self, value: i32) -> Result<Self> {
|
||||||
|
self.builder.write_int32(9, value)?;
|
||||||
|
Ok(self)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn json_name(mut self, value: &str) -> Result<Self> {
|
||||||
|
self.builder.write_string(10, value)?;
|
||||||
|
Ok(self)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn proto3_optional(mut self, value: bool) -> Result<Self> {
|
||||||
|
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<Self> {
|
||||||
|
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> {
|
||||||
|
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<Self> {
|
||||||
|
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<i32> {
|
||||||
|
let (bytes, _) = self.0.get_value(3)?;
|
||||||
|
let (val, _) = crate::read_varint(bytes)?;
|
||||||
|
Ok(val as i32)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn end(&self) -> Result<i32> {
|
||||||
|
let (bytes, _) = self.0.get_value(4)?;
|
||||||
|
let (val, _) = crate::read_varint(bytes)?;
|
||||||
|
Ok(val as i32)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn semantic(&self) -> Result<i32> {
|
||||||
|
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> {
|
||||||
|
self.builder.write_int32(1, value)?;
|
||||||
|
Ok(self)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn source_file(mut self, value: &str) -> Result<Self> {
|
||||||
|
self.builder.write_string(2, value)?;
|
||||||
|
Ok(self)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn begin(mut self, value: i32) -> Result<Self> {
|
||||||
|
self.builder.write_int32(3, value)?;
|
||||||
|
Ok(self)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn end(mut self, value: i32) -> Result<Self> {
|
||||||
|
self.builder.write_int32(4, value)?;
|
||||||
|
Ok(self)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn semantic(mut self, value: i32) -> Result<Self> {
|
||||||
|
self.builder.write_varint(5, value as u64)?;
|
||||||
|
Ok(self)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn finish(self) -> Result<&'b mut [u8]> {
|
||||||
|
self.builder.finish()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
pub mod google {
|
||||||
|
pub mod protobuf {
|
||||||
|
pub mod descriptor;
|
||||||
|
pub mod compiler {
|
||||||
|
pub mod plugin;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user