use parser::Parser;
use parser::Loc;
pub use parser::ParserError;
pub use parser::ParserErrorWithLocation;
use protobuf_codegen::float;
use str_lit::StrLit;
#[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(Vec<Field>),
}
#[derive(Debug, Clone, PartialEq)]
pub struct Field {
pub name: String,
pub rule: Rule,
pub typ: FieldType,
pub number: i32,
pub default: Option<ProtobufConstant>,
pub packed: Option<bool>,
pub deprecated: bool,
}
#[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<Field>,
pub oneofs: Vec<OneOf>,
pub reserved_nums: Vec<FieldNumberRange>,
pub reserved_names: Vec<String>,
pub messages: Vec<Message>,
pub enums: Vec<Enumeration>,
}
#[derive(Debug, Clone)]
pub struct EnumValue {
pub name: String,
pub number: i32,
}
#[derive(Debug, Clone, Default)]
pub struct EnumOptions {
pub allow_alias: bool,
}
#[derive(Debug, Clone)]
pub struct Enumeration {
pub name: String,
pub values: Vec<EnumValue>,
pub options: EnumOptions,
}
#[derive(Debug, Clone, Default)]
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)]
pub struct ProtobufOption {
pub name: String,
pub value: ProtobufConstant,
}
#[derive(Debug, Default, Clone)]
pub struct FileDescriptor {
pub import_paths: Vec<String>,
pub package: 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 })
}
}
}
}