use std::fmt;
use prost::{
bytes::{Buf, BufMut},
encoding::{encode_key, skip_field, DecodeContext, WireType},
DecodeError, Message,
};
pub(crate) use prost_types::{
enum_descriptor_proto, field_descriptor_proto, uninterpreted_option, EnumOptions,
EnumValueOptions, ExtensionRangeOptions, FieldOptions, FileOptions, MessageOptions,
MethodOptions, OneofOptions, ServiceOptions, SourceCodeInfo, UninterpretedOption,
};
#[derive(Clone, PartialEq, Message)]
pub(crate) struct FileDescriptorSet {
#[prost(message, repeated, tag = "1")]
pub file: Vec<FileDescriptorProto>,
}
#[derive(Clone, PartialEq, Message)]
pub(crate) struct FileDescriptorProto {
#[prost(string, optional, tag = "1")]
pub name: Option<String>,
#[prost(string, optional, tag = "2")]
pub package: Option<String>,
#[prost(string, repeated, tag = "3")]
pub dependency: Vec<String>,
#[prost(int32, repeated, packed = "false", tag = "10")]
pub public_dependency: Vec<i32>,
#[prost(int32, repeated, packed = "false", tag = "11")]
pub weak_dependency: Vec<i32>,
#[prost(message, repeated, tag = "4")]
pub message_type: Vec<DescriptorProto>,
#[prost(message, repeated, tag = "5")]
pub(crate) enum_type: Vec<EnumDescriptorProto>,
#[prost(message, repeated, tag = "6")]
pub service: Vec<ServiceDescriptorProto>,
#[prost(message, repeated, tag = "7")]
pub extension: Vec<FieldDescriptorProto>,
#[prost(message, optional, tag = "8")]
pub options: Option<Options<FileOptions>>,
#[prost(message, optional, tag = "9")]
pub source_code_info: Option<SourceCodeInfo>,
#[prost(string, optional, tag = "12")]
pub syntax: Option<String>,
}
#[derive(Clone, PartialEq, Message)]
pub(crate) struct DescriptorProto {
#[prost(string, optional, tag = "1")]
pub name: Option<String>,
#[prost(message, repeated, tag = "2")]
pub field: Vec<FieldDescriptorProto>,
#[prost(message, repeated, tag = "6")]
pub extension: Vec<FieldDescriptorProto>,
#[prost(message, repeated, tag = "3")]
pub nested_type: Vec<DescriptorProto>,
#[prost(message, repeated, tag = "4")]
pub(crate) enum_type: Vec<EnumDescriptorProto>,
#[prost(message, repeated, tag = "5")]
pub extension_range: Vec<descriptor_proto::ExtensionRange>,
#[prost(message, repeated, tag = "8")]
pub oneof_decl: Vec<OneofDescriptorProto>,
#[prost(message, optional, tag = "7")]
pub options: Option<Options<MessageOptions>>,
#[prost(message, repeated, tag = "9")]
pub reserved_range: Vec<descriptor_proto::ReservedRange>,
#[prost(string, repeated, tag = "10")]
pub reserved_name: Vec<String>,
}
pub(crate) mod descriptor_proto {
pub(crate) use prost_types::descriptor_proto::ReservedRange;
use super::*;
#[derive(Clone, PartialEq, Message)]
pub(crate) struct ExtensionRange {
#[prost(int32, optional, tag = "1")]
pub start: Option<i32>,
#[prost(int32, optional, tag = "2")]
pub end: Option<i32>,
#[prost(message, optional, tag = "3")]
pub options: Option<Options<ExtensionRangeOptions>>,
}
}
#[derive(Clone, PartialEq, Message)]
pub(crate) struct FieldDescriptorProto {
#[prost(string, optional, tag = "1")]
pub name: Option<String>,
#[prost(int32, optional, tag = "3")]
pub number: Option<i32>,
#[prost(enumeration = "field_descriptor_proto::Label", optional, tag = "4")]
pub label: Option<i32>,
#[prost(enumeration = "field_descriptor_proto::Type", optional, tag = "5")]
pub r#type: Option<i32>,
#[prost(string, optional, tag = "6")]
pub type_name: Option<String>,
#[prost(string, optional, tag = "2")]
pub extendee: Option<String>,
#[prost(string, optional, tag = "7")]
pub default_value: Option<String>,
#[prost(int32, optional, tag = "9")]
pub oneof_index: Option<i32>,
#[prost(string, optional, tag = "10")]
pub json_name: Option<String>,
#[prost(message, optional, tag = "8")]
pub options: Option<Options<FieldOptions>>,
#[prost(bool, optional, tag = "17")]
pub proto3_optional: Option<bool>,
}
#[derive(Clone, PartialEq, Message)]
pub(crate) struct OneofDescriptorProto {
#[prost(string, optional, tag = "1")]
pub name: Option<String>,
#[prost(message, optional, tag = "2")]
pub options: Option<Options<OneofOptions>>,
}
#[derive(Clone, PartialEq, Message)]
pub(crate) struct EnumDescriptorProto {
#[prost(string, optional, tag = "1")]
pub name: Option<String>,
#[prost(message, repeated, tag = "2")]
pub value: Vec<EnumValueDescriptorProto>,
#[prost(message, optional, tag = "3")]
pub options: Option<Options<EnumOptions>>,
#[prost(message, repeated, tag = "4")]
pub reserved_range: Vec<enum_descriptor_proto::EnumReservedRange>,
#[prost(string, repeated, tag = "5")]
pub reserved_name: Vec<String>,
}
#[derive(Clone, PartialEq, Message)]
pub(crate) struct EnumValueDescriptorProto {
#[prost(string, optional, tag = "1")]
pub name: Option<String>,
#[prost(int32, optional, tag = "2")]
pub number: Option<i32>,
#[prost(message, optional, tag = "3")]
pub options: Option<Options<EnumValueOptions>>,
}
#[derive(Clone, PartialEq, Message)]
pub(crate) struct ServiceDescriptorProto {
#[prost(string, optional, tag = "1")]
pub name: Option<String>,
#[prost(message, repeated, tag = "2")]
pub method: Vec<MethodDescriptorProto>,
#[prost(message, optional, tag = "3")]
pub options: Option<Options<ServiceOptions>>,
}
#[derive(Clone, PartialEq, Message)]
pub(crate) struct MethodDescriptorProto {
#[prost(string, optional, tag = "1")]
pub name: Option<String>,
#[prost(string, optional, tag = "2")]
pub input_type: Option<String>,
#[prost(string, optional, tag = "3")]
pub output_type: Option<String>,
#[prost(message, optional, tag = "4")]
pub options: Option<Options<MethodOptions>>,
#[prost(bool, optional, tag = "5", default = "false")]
pub client_streaming: Option<bool>,
#[prost(bool, optional, tag = "6", default = "false")]
pub server_streaming: Option<bool>,
}
#[derive(Clone, Default, PartialEq)]
pub(crate) struct Options<T> {
pub(crate) encoded: Vec<u8>,
pub(crate) value: T,
}
impl FileDescriptorProto {
pub(crate) fn from_prost(file: prost_types::FileDescriptorProto) -> FileDescriptorProto {
FileDescriptorProto {
name: file.name,
package: file.package,
dependency: file.dependency,
public_dependency: file.public_dependency,
weak_dependency: file.weak_dependency,
message_type: file
.message_type
.into_iter()
.map(DescriptorProto::from_prost)
.collect(),
enum_type: file
.enum_type
.into_iter()
.map(EnumDescriptorProto::from_prost)
.collect(),
service: file
.service
.into_iter()
.map(ServiceDescriptorProto::from_prost)
.collect(),
extension: file
.extension
.into_iter()
.map(FieldDescriptorProto::from_prost)
.collect(),
options: file.options.map(Options::from_prost),
source_code_info: file.source_code_info,
syntax: file.syntax,
}
}
pub(crate) fn to_prost(&self) -> prost_types::FileDescriptorProto {
prost_types::FileDescriptorProto {
name: self.name.clone(),
package: self.package.clone(),
dependency: self.dependency.clone(),
public_dependency: self.public_dependency.clone(),
weak_dependency: self.weak_dependency.clone(),
message_type: self
.message_type
.iter()
.map(DescriptorProto::to_prost)
.collect(),
enum_type: self
.enum_type
.iter()
.map(EnumDescriptorProto::to_prost)
.collect(),
service: self
.service
.iter()
.map(ServiceDescriptorProto::to_prost)
.collect(),
extension: self
.extension
.iter()
.map(FieldDescriptorProto::to_prost)
.collect(),
options: self.options.as_ref().map(Options::to_prost),
source_code_info: self.source_code_info.clone(),
syntax: self.syntax.clone(),
}
}
}
impl DescriptorProto {
pub(crate) fn from_prost(file: prost_types::DescriptorProto) -> DescriptorProto {
DescriptorProto {
name: file.name,
field: file
.field
.into_iter()
.map(FieldDescriptorProto::from_prost)
.collect(),
extension: file
.extension
.into_iter()
.map(FieldDescriptorProto::from_prost)
.collect(),
nested_type: file
.nested_type
.into_iter()
.map(DescriptorProto::from_prost)
.collect(),
enum_type: file
.enum_type
.into_iter()
.map(EnumDescriptorProto::from_prost)
.collect(),
extension_range: file
.extension_range
.into_iter()
.map(descriptor_proto::ExtensionRange::from_prost)
.collect(),
oneof_decl: file
.oneof_decl
.into_iter()
.map(OneofDescriptorProto::from_prost)
.collect(),
options: file.options.map(Options::from_prost),
reserved_range: file.reserved_range,
reserved_name: file.reserved_name,
}
}
pub(crate) fn to_prost(&self) -> prost_types::DescriptorProto {
prost_types::DescriptorProto {
name: self.name.clone(),
field: self
.field
.iter()
.map(FieldDescriptorProto::to_prost)
.collect(),
extension: self
.extension
.iter()
.map(FieldDescriptorProto::to_prost)
.collect(),
nested_type: self
.nested_type
.iter()
.map(DescriptorProto::to_prost)
.collect(),
enum_type: self
.enum_type
.iter()
.map(EnumDescriptorProto::to_prost)
.collect(),
extension_range: self
.extension_range
.iter()
.map(descriptor_proto::ExtensionRange::to_prost)
.collect(),
oneof_decl: self
.oneof_decl
.iter()
.map(OneofDescriptorProto::to_prost)
.collect(),
options: self.options.as_ref().map(Options::to_prost),
reserved_range: self.reserved_range.clone(),
reserved_name: self.reserved_name.clone(),
}
}
}
impl FieldDescriptorProto {
pub(crate) fn from_prost(file: prost_types::FieldDescriptorProto) -> FieldDescriptorProto {
FieldDescriptorProto {
name: file.name,
number: file.number,
label: file.label,
r#type: file.r#type,
type_name: file.type_name,
extendee: file.extendee,
default_value: file.default_value,
oneof_index: file.oneof_index,
json_name: file.json_name,
options: file.options.map(Options::from_prost),
proto3_optional: file.proto3_optional,
}
}
pub(crate) fn to_prost(&self) -> prost_types::FieldDescriptorProto {
prost_types::FieldDescriptorProto {
name: self.name.clone(),
number: self.number,
label: self.label,
r#type: self.r#type,
type_name: self.type_name.clone(),
extendee: self.extendee.clone(),
default_value: self.default_value.clone(),
oneof_index: self.oneof_index,
json_name: self.json_name.clone(),
options: self.options.as_ref().map(Options::to_prost),
proto3_optional: self.proto3_optional,
}
}
}
impl OneofDescriptorProto {
pub(crate) fn from_prost(file: prost_types::OneofDescriptorProto) -> OneofDescriptorProto {
OneofDescriptorProto {
name: file.name,
options: file.options.map(Options::from_prost),
}
}
pub(crate) fn to_prost(&self) -> prost_types::OneofDescriptorProto {
prost_types::OneofDescriptorProto {
name: self.name.clone(),
options: self.options.as_ref().map(Options::to_prost),
}
}
}
impl descriptor_proto::ExtensionRange {
pub(crate) fn from_prost(
file: prost_types::descriptor_proto::ExtensionRange,
) -> descriptor_proto::ExtensionRange {
descriptor_proto::ExtensionRange {
start: file.start,
end: file.end,
options: file.options.map(Options::from_prost),
}
}
pub(crate) fn to_prost(&self) -> prost_types::descriptor_proto::ExtensionRange {
prost_types::descriptor_proto::ExtensionRange {
start: self.start,
end: self.end,
options: self.options.as_ref().map(Options::to_prost),
}
}
}
impl EnumDescriptorProto {
pub(crate) fn from_prost(file: prost_types::EnumDescriptorProto) -> EnumDescriptorProto {
EnumDescriptorProto {
name: file.name,
value: file
.value
.into_iter()
.map(EnumValueDescriptorProto::from_prost)
.collect(),
options: file.options.map(Options::from_prost),
reserved_range: file.reserved_range,
reserved_name: file.reserved_name,
}
}
pub(crate) fn to_prost(&self) -> prost_types::EnumDescriptorProto {
prost_types::EnumDescriptorProto {
name: self.name.clone(),
value: self
.value
.iter()
.map(EnumValueDescriptorProto::to_prost)
.collect(),
options: self.options.as_ref().map(Options::to_prost),
reserved_range: self.reserved_range.clone(),
reserved_name: self.reserved_name.clone(),
}
}
}
impl EnumValueDescriptorProto {
pub(crate) fn from_prost(
file: prost_types::EnumValueDescriptorProto,
) -> EnumValueDescriptorProto {
EnumValueDescriptorProto {
name: file.name,
number: file.number,
options: file.options.map(Options::from_prost),
}
}
pub(crate) fn to_prost(&self) -> prost_types::EnumValueDescriptorProto {
prost_types::EnumValueDescriptorProto {
name: self.name.clone(),
number: self.number,
options: self.options.as_ref().map(Options::to_prost),
}
}
}
impl ServiceDescriptorProto {
pub(crate) fn from_prost(file: prost_types::ServiceDescriptorProto) -> ServiceDescriptorProto {
ServiceDescriptorProto {
name: file.name,
method: file
.method
.into_iter()
.map(MethodDescriptorProto::from_prost)
.collect(),
options: file.options.map(Options::from_prost),
}
}
pub(crate) fn to_prost(&self) -> prost_types::ServiceDescriptorProto {
prost_types::ServiceDescriptorProto {
name: self.name.clone(),
method: self
.method
.iter()
.map(MethodDescriptorProto::to_prost)
.collect(),
options: self.options.as_ref().map(Options::to_prost),
}
}
}
impl MethodDescriptorProto {
pub(crate) fn from_prost(file: prost_types::MethodDescriptorProto) -> MethodDescriptorProto {
MethodDescriptorProto {
name: file.name,
input_type: file.input_type,
output_type: file.output_type,
options: file.options.map(Options::from_prost),
client_streaming: file.client_streaming,
server_streaming: file.server_streaming,
}
}
pub(crate) fn to_prost(&self) -> prost_types::MethodDescriptorProto {
prost_types::MethodDescriptorProto {
name: self.name.clone(),
input_type: self.input_type.clone(),
output_type: self.output_type.clone(),
options: self.options.as_ref().map(Options::to_prost),
client_streaming: self.client_streaming,
server_streaming: self.server_streaming,
}
}
}
impl<T> Options<T>
where
T: Message + Clone,
{
fn from_prost(options: T) -> Self {
Options {
encoded: options.encode_to_vec(),
value: options,
}
}
fn to_prost(&self) -> T {
self.value.clone()
}
}
impl<T> fmt::Debug for Options<T>
where
T: fmt::Debug,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.value.fmt(f)
}
}
impl<T> Message for Options<T>
where
T: Message + Default,
{
fn encode_raw(&self, buf: &mut impl BufMut)
where
Self: Sized,
{
buf.put(self.encoded.as_slice());
}
fn merge_field(
&mut self,
tag: u32,
wire_type: WireType,
buf: &mut impl Buf,
ctx: DecodeContext,
) -> Result<(), DecodeError>
where
Self: Sized,
{
struct CopyBufAdapter<'a, B> {
dest: &'a mut Vec<u8>,
src: &'a mut B,
}
impl<B> Buf for CopyBufAdapter<'_, B>
where
B: Buf,
{
fn advance(&mut self, cnt: usize) {
self.dest.put((&mut self.src).take(cnt));
}
fn chunk(&self) -> &[u8] {
self.src.chunk()
}
fn remaining(&self) -> usize {
self.src.remaining()
}
}
encode_key(tag, wire_type, &mut self.encoded);
let start = self.encoded.len();
skip_field(
wire_type,
tag,
&mut CopyBufAdapter {
dest: &mut self.encoded,
src: buf,
},
ctx.clone(),
)?;
self.value
.merge_field(tag, wire_type, &mut &self.encoded[start..], ctx)?;
Ok(())
}
fn encoded_len(&self) -> usize {
self.encoded.len()
}
fn clear(&mut self) {
self.encoded.clear();
self.value.clear();
}
}