use parser::Loc;
use parser::Parser;
pub use parser::ParserError;
pub use parser::ParserErrorWithLocation;
use protobuf::text_format::lexer::StrLit;
use protobuf_codegen::float;
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
pub enum Syntax {
Proto2,
Proto3,
}
impl Default for Syntax {
fn default() -> Syntax {
Syntax::Proto2
}
}
#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
pub enum Rule {
Optional,
Repeated,
Required,
}
#[derive(Debug, Clone, PartialEq)]
pub enum FieldType {
Int32,
Int64,
Uint32,
Uint64,
Sint32,
Sint64,
Bool,
Fixed64,
Sfixed64,
Double,
String,
Bytes,
Fixed32,
Sfixed32,
Float,
MessageOrEnum(String),
Map(Box<(FieldType, FieldType)>),
Group { name: String, fields: Vec<Field> },
}
#[derive(Debug, Clone, PartialEq)]
pub struct Field {
pub name: String,
pub rule: Rule,
pub typ: FieldType,
pub number: i32,
pub options: Vec<ProtobufOption>,
}
#[derive(Debug, Clone, PartialEq)]
pub enum FieldOrOneOf {
Field(Field),
OneOf(OneOf),
}
#[derive(Default, Debug, Eq, PartialEq, Copy, Clone)]
pub struct FieldNumberRange {
pub from: i32,
pub to: i32,
}
#[derive(Debug, Clone, Default)]
pub struct Message {
pub name: String,
pub fields: Vec<FieldOrOneOf>,
pub reserved_nums: Vec<FieldNumberRange>,
pub reserved_names: Vec<String>,
pub messages: Vec<Message>,
pub enums: Vec<Enumeration>,
pub options: Vec<ProtobufOption>,
}
impl Message {
pub fn regular_fields_including_in_oneofs(&self) -> Vec<&Field> {
self.fields
.iter()
.flat_map(|fo| match fo {
FieldOrOneOf::Field(f) => vec![f],
FieldOrOneOf::OneOf(o) => o.fields.iter().collect(),
})
.collect()
}
#[cfg(test)]
pub fn regular_fields_for_test(&self) -> Vec<&Field> {
self.fields
.iter()
.flat_map(|fo| match fo {
FieldOrOneOf::Field(f) => Some(f),
FieldOrOneOf::OneOf(_) => None,
})
.collect()
}
#[cfg(test)]
pub fn oneofs_for_test(&self) -> Vec<&OneOf> {
self.fields
.iter()
.flat_map(|fo| match fo {
FieldOrOneOf::Field(_) => None,
FieldOrOneOf::OneOf(o) => Some(o),
})
.collect()
}
}
#[derive(Debug, Clone)]
pub struct EnumValue {
pub name: String,
pub number: i32,
}
#[derive(Debug, Clone)]
pub struct Enumeration {
pub name: String,
pub values: Vec<EnumValue>,
pub options: Vec<ProtobufOption>,
}
#[derive(Debug, Clone, Default, PartialEq)]
pub struct OneOf {
pub name: String,
pub fields: Vec<Field>,
}
#[derive(Debug, Clone)]
pub struct Extension {
pub extendee: String,
pub field: Field,
}
#[derive(Debug, Clone, PartialEq)]
pub enum ProtobufConstant {
U64(u64),
I64(i64),
F64(f64), Bool(bool),
Ident(String),
String(StrLit),
BracedExpr(String),
}
impl ProtobufConstant {
pub fn format(&self) -> String {
match *self {
ProtobufConstant::U64(u) => u.to_string(),
ProtobufConstant::I64(i) => i.to_string(),
ProtobufConstant::F64(f) => float::format_protobuf_float(f),
ProtobufConstant::Bool(b) => b.to_string(),
ProtobufConstant::Ident(ref i) => i.clone(),
ProtobufConstant::String(ref s) => s.quoted(),
ProtobufConstant::BracedExpr(ref s) => s.clone(),
}
}
}
#[derive(Debug, Clone, PartialEq)]
pub struct ProtobufOption {
pub name: String,
pub value: ProtobufConstant,
}
#[derive(Debug, Clone, Eq, PartialEq)]
pub enum ImportVis {
Default,
Public,
Weak,
}
impl Default for ImportVis {
fn default() -> Self {
ImportVis::Default
}
}
#[derive(Debug, Default, Clone)]
pub struct Import {
pub path: String,
pub vis: ImportVis,
}
#[derive(Debug, Default, Clone)]
pub struct FileDescriptor {
pub imports: Vec<Import>,
pub package: Option<String>,
pub syntax: Syntax,
pub messages: Vec<Message>,
pub enums: Vec<Enumeration>,
pub extensions: Vec<Extension>,
pub options: Vec<ProtobufOption>,
}
impl FileDescriptor {
pub fn parse<S: AsRef<str>>(file: S) -> Result<Self, ParserErrorWithLocation> {
let mut parser = Parser::new(file.as_ref());
match parser.next_proto() {
Ok(r) => Ok(r),
Err(error) => {
let Loc { line, col } = parser.loc();
Err(ParserErrorWithLocation { error, line, col })
}
}
}
}