1use std::ops::RangeInclusive;
2use std::str;
3
4use protobuf_support::lexer::int;
5use protobuf_support::lexer::lexer_impl::LexerError;
6use protobuf_support::lexer::num_lit::NumLit;
7use protobuf_support::lexer::parser_language::ParserLanguage;
8use protobuf_support::lexer::str_lit::StrLitDecodeError;
9use protobuf_support::lexer::token::Token;
10use protobuf_support::lexer::tokenizer::Tokenizer;
11use protobuf_support::lexer::tokenizer::TokenizerError;
12
13use crate::model::AnyTypeUrl;
14use crate::model::ProtobufConstantMessageFieldName;
15use crate::proto_path::ProtoPathBuf;
16use crate::protobuf_abs_path::ProtobufAbsPath;
17use crate::protobuf_ident::ProtobufIdent;
18use crate::protobuf_path::ProtobufPath;
19use crate::protobuf_rel_path::ProtobufRelPath;
20use crate::pure::model;
21use crate::pure::model::EnumValue;
22use crate::pure::model::Enumeration;
23use crate::pure::model::Extension;
24use crate::pure::model::Field;
25use crate::pure::model::FieldOrOneOf;
26use crate::pure::model::FieldType;
27use crate::pure::model::FileDescriptor;
28use crate::pure::model::Group;
29use crate::pure::model::ImportVis;
30use crate::pure::model::Message;
31use crate::pure::model::Method;
32use crate::pure::model::OneOf;
33use crate::pure::model::ProtobufConstant;
34use crate::pure::model::ProtobufConstantMessage;
35use crate::pure::model::ProtobufOption;
36use crate::pure::model::ProtobufOptionName;
37use crate::pure::model::ProtobufOptionNameExt;
38use crate::pure::model::ProtobufOptionNamePart;
39use crate::pure::model::Rule;
40use crate::pure::model::Service;
41use crate::pure::model::Syntax;
42use crate::pure::model::WithLoc;
43
44#[derive(Debug, thiserror::Error)]
46pub(crate) enum ParserError {
47 #[error("{0}")]
48 TokenizerError(#[source] TokenizerError),
49 #[error("incorrect input")]
51 IncorrectInput,
52 #[error("expecting a constant")]
53 ExpectConstant,
54 #[error("unknown syntax")]
55 UnknownSyntax,
56 #[error("integer overflow")]
57 IntegerOverflow,
58 #[error("label not allowed")]
59 LabelNotAllowed,
60 #[error("label required")]
61 LabelRequired,
62 #[error("group name should start with upper case")]
63 GroupNameShouldStartWithUpperCase,
64 #[error("map field not allowed")]
65 MapFieldNotAllowed,
66 #[error("string literal decode error: {0}")]
67 StrLitDecodeError(#[source] StrLitDecodeError),
68 #[error("lexer error: {0}")]
69 LexerError(#[source] LexerError),
70 #[error("oneof in group")]
71 OneOfInGroup,
72 #[error("oneof in oneof")]
73 OneOfInOneOf,
74 #[error("oneof in extend")]
75 OneOfInExtend,
76}
77
78impl From<TokenizerError> for ParserError {
79 fn from(e: TokenizerError) -> Self {
80 ParserError::TokenizerError(e)
81 }
82}
83
84impl From<StrLitDecodeError> for ParserError {
85 fn from(e: StrLitDecodeError) -> Self {
86 ParserError::StrLitDecodeError(e)
87 }
88}
89
90impl From<LexerError> for ParserError {
91 fn from(e: LexerError) -> Self {
92 ParserError::LexerError(e)
93 }
94}
95
96impl From<int::Overflow> for ParserError {
97 fn from(_: int::Overflow) -> Self {
98 ParserError::IntegerOverflow
99 }
100}
101
102#[derive(Debug, thiserror::Error)]
103#[error("at {line}:{col}: {error}")]
104pub struct ParserErrorWithLocation {
105 #[source]
106 pub error: anyhow::Error,
107 pub line: u32,
109 pub col: u32,
111}
112
113trait ToI32 {
114 fn to_i32(&self) -> anyhow::Result<i32>;
115}
116
117trait ToI64 {
118 fn to_i64(&self) -> anyhow::Result<i64>;
119}
120
121impl ToI32 for u64 {
122 fn to_i32(&self) -> anyhow::Result<i32> {
123 if *self <= i32::max_value() as u64 {
124 Ok(*self as i32)
125 } else {
126 Err(ParserError::IntegerOverflow.into())
127 }
128 }
129}
130
131impl ToI32 for i64 {
132 fn to_i32(&self) -> anyhow::Result<i32> {
133 if *self <= i32::max_value() as i64 && *self >= i32::min_value() as i64 {
134 Ok(*self as i32)
135 } else {
136 Err(ParserError::IntegerOverflow.into())
137 }
138 }
139}
140
141impl ToI64 for u64 {
142 fn to_i64(&self) -> anyhow::Result<i64> {
143 if *self <= i64::max_value() as u64 {
144 Ok(*self as i64)
145 } else {
146 Err(ParserError::IntegerOverflow.into())
147 }
148 }
149}
150
151#[derive(Clone)]
152pub(crate) struct Parser<'a> {
153 pub tokenizer: Tokenizer<'a>,
154 syntax: Syntax,
155}
156
157#[derive(Copy, Clone)]
158enum MessageBodyParseMode {
159 MessageProto2,
160 MessageProto3,
161 Oneof,
162 ExtendProto2,
163 ExtendProto3,
164}
165
166impl MessageBodyParseMode {
167 fn label_allowed(&self, label: Rule) -> bool {
168 match label {
169 Rule::Repeated => match *self {
170 MessageBodyParseMode::MessageProto2
171 | MessageBodyParseMode::MessageProto3
172 | MessageBodyParseMode::ExtendProto2
173 | MessageBodyParseMode::ExtendProto3 => true,
174 MessageBodyParseMode::Oneof => false,
175 },
176 Rule::Optional => match *self {
177 MessageBodyParseMode::MessageProto2 | MessageBodyParseMode::ExtendProto2 => true,
178 MessageBodyParseMode::MessageProto3 | MessageBodyParseMode::ExtendProto3 => true,
179 MessageBodyParseMode::Oneof => false,
180 },
181 Rule::Required => match *self {
182 MessageBodyParseMode::MessageProto2 | MessageBodyParseMode::ExtendProto2 => true,
183 MessageBodyParseMode::MessageProto3 | MessageBodyParseMode::ExtendProto3 => false,
184 MessageBodyParseMode::Oneof => false,
185 },
186 }
187 }
188
189 fn some_label_required(&self) -> bool {
190 match *self {
191 MessageBodyParseMode::MessageProto2 | MessageBodyParseMode::ExtendProto2 => true,
192 MessageBodyParseMode::MessageProto3
193 | MessageBodyParseMode::ExtendProto3
194 | MessageBodyParseMode::Oneof => false,
195 }
196 }
197
198 fn map_allowed(&self) -> bool {
199 match *self {
200 MessageBodyParseMode::MessageProto2
201 | MessageBodyParseMode::MessageProto3
202 | MessageBodyParseMode::ExtendProto2
203 | MessageBodyParseMode::ExtendProto3 => true,
204 MessageBodyParseMode::Oneof => false,
205 }
206 }
207
208 fn is_most_non_fields_allowed(&self) -> bool {
209 match *self {
210 MessageBodyParseMode::MessageProto2 | MessageBodyParseMode::MessageProto3 => true,
211 MessageBodyParseMode::ExtendProto2
212 | MessageBodyParseMode::ExtendProto3
213 | MessageBodyParseMode::Oneof => false,
214 }
215 }
216
217 fn is_option_allowed(&self) -> bool {
218 match *self {
219 MessageBodyParseMode::MessageProto2
220 | MessageBodyParseMode::MessageProto3
221 | MessageBodyParseMode::Oneof => true,
222 MessageBodyParseMode::ExtendProto2 | MessageBodyParseMode::ExtendProto3 => false,
223 }
224 }
225
226 fn is_extensions_allowed(&self) -> bool {
227 match self {
228 MessageBodyParseMode::MessageProto2 => true,
229 _ => false,
230 }
231 }
232}
233
234#[derive(Default)]
235pub(crate) struct MessageBody {
236 pub fields: Vec<WithLoc<FieldOrOneOf>>,
237 pub reserved_nums: Vec<RangeInclusive<i32>>,
238 pub reserved_names: Vec<String>,
239 pub messages: Vec<WithLoc<Message>>,
240 pub enums: Vec<WithLoc<Enumeration>>,
241 pub options: Vec<ProtobufOption>,
242 pub extension_ranges: Vec<RangeInclusive<i32>>,
243 pub extensions: Vec<WithLoc<Extension>>,
244}
245
246trait NumLitEx {
247 fn to_option_value(&self, sign_is_plus: bool) -> anyhow::Result<ProtobufConstant>;
248}
249
250impl NumLitEx for NumLit {
251 fn to_option_value(&self, sign_is_plus: bool) -> anyhow::Result<ProtobufConstant> {
252 Ok(match (*self, sign_is_plus) {
253 (NumLit::U64(u), true) => ProtobufConstant::U64(u),
254 (NumLit::F64(f), true) => ProtobufConstant::F64(f),
255 (NumLit::U64(u), false) => {
256 ProtobufConstant::I64(int::neg(u).map_err(|_| ParserError::IntegerOverflow)?)
257 }
258 (NumLit::F64(f), false) => ProtobufConstant::F64(-f),
259 })
260 }
261}
262
263impl<'a> Parser<'a> {
264 pub(crate) fn new(input: &'a str) -> Parser<'a> {
265 Parser {
266 tokenizer: Tokenizer::new(input, ParserLanguage::Proto),
267 syntax: Syntax::Proto2,
268 }
269 }
270
271 fn next_full_ident(&mut self) -> anyhow::Result<ProtobufPath> {
275 let mut full_ident = String::new();
276 if self.tokenizer.next_symbol_if_eq('.')? {
278 full_ident.push('.');
279 }
280 full_ident.push_str(&self.tokenizer.next_ident()?);
281 while self.tokenizer.next_symbol_if_eq('.')? {
282 full_ident.push('.');
283 full_ident.push_str(&self.tokenizer.next_ident()?);
284 }
285 Ok(ProtobufPath::new(full_ident))
286 }
287
288 fn next_full_ident_rel(&mut self) -> anyhow::Result<ProtobufRelPath> {
290 let mut full_ident = String::new();
291 full_ident.push_str(&self.tokenizer.next_ident()?);
292 while self.tokenizer.next_symbol_if_eq('.')? {
293 full_ident.push('.');
294 full_ident.push_str(&self.tokenizer.next_ident()?);
295 }
296 Ok(ProtobufRelPath::new(full_ident))
297 }
298
299 fn next_empty_statement_opt(&mut self) -> anyhow::Result<Option<()>> {
301 if self.tokenizer.next_symbol_if_eq(';')? {
302 Ok(Some(()))
303 } else {
304 Ok(None)
305 }
306 }
307
308 fn next_message_or_enum_type(&mut self) -> anyhow::Result<ProtobufPath> {
313 self.next_full_ident()
314 }
315
316 fn next_group_name(&mut self) -> anyhow::Result<String> {
318 let mut clone = self.clone();
320 let ident = clone.tokenizer.next_ident()?;
321 if !ident.chars().next().unwrap().is_ascii_uppercase() {
322 return Err(ParserError::GroupNameShouldStartWithUpperCase.into());
323 }
324 *self = clone;
325 Ok(ident)
326 }
327
328 fn next_bool_lit_opt(&mut self) -> anyhow::Result<Option<bool>> {
332 Ok(if self.tokenizer.next_ident_if_eq("true")? {
333 Some(true)
334 } else if self.tokenizer.next_ident_if_eq("false")? {
335 Some(false)
336 } else {
337 None
338 })
339 }
340
341 fn next_num_lit(&mut self) -> anyhow::Result<NumLit> {
344 self.tokenizer
345 .next_token_check_map(|token| Ok(token.to_num_lit()?))
346 }
347
348 fn next_message_constant_field_name(
349 &mut self,
350 ) -> anyhow::Result<ProtobufConstantMessageFieldName> {
351 if self.tokenizer.next_symbol_if_eq('[')? {
352 let n = self.next_full_ident()?;
353 if self.tokenizer.next_symbol_if_eq('/')? {
354 let prefix = format!("{}", n);
355 let full_type_name = self.next_full_ident()?;
356 self.tokenizer
357 .next_symbol_expect_eq(']', "message constant")?;
358 Ok(ProtobufConstantMessageFieldName::AnyTypeUrl(AnyTypeUrl {
359 prefix,
360 full_type_name,
361 }))
362 } else {
363 self.tokenizer
364 .next_symbol_expect_eq(']', "message constant")?;
365 Ok(ProtobufConstantMessageFieldName::Extension(n))
366 }
367 } else {
368 let n = self.tokenizer.next_ident()?;
369 Ok(ProtobufConstantMessageFieldName::Regular(n))
370 }
371 }
372
373 fn next_message_constant(&mut self) -> anyhow::Result<ProtobufConstantMessage> {
374 let mut r = ProtobufConstantMessage::default();
375 self.tokenizer
376 .next_symbol_expect_eq('{', "message constant")?;
377 while !self.tokenizer.lookahead_is_symbol('}')? {
378 let n = self.next_message_constant_field_name()?;
379 let v = self.next_field_value()?;
380
381 self.tokenizer.next_symbol_if_in(&[',', ';'])?;
391
392 r.fields.insert(n, v);
393 }
394 self.tokenizer
395 .next_symbol_expect_eq('}', "message constant")?;
396 Ok(r)
397 }
398
399 fn next_list_constant(&mut self) -> anyhow::Result<Vec<ProtobufConstant>> {
400 self.tokenizer.next_symbol_expect_eq('[', "list constant")?;
401
402 let mut list = Vec::new();
403
404 if self.tokenizer.next_symbol_if_eq(']')? {
406 return Ok(list);
407 }
408
409 list.push(self.next_constant()?);
410 while self.tokenizer.next_symbol_if_eq(',')? {
411 list.push(self.next_constant()?);
412 }
413
414 self.tokenizer.next_symbol_expect_eq(']', "list constant")?;
415
416 Ok(list)
417 }
418
419 fn next_constant(&mut self) -> anyhow::Result<ProtobufConstant> {
422 if self.tokenizer.lookahead_is_symbol('{')? {
424 return Ok(ProtobufConstant::Message(self.next_message_constant()?));
425 }
426
427 if self.tokenizer.lookahead_is_symbol('[')? {
428 return Ok(ProtobufConstant::Repeated(self.next_list_constant()?));
429 }
430
431 if let Some(b) = self.next_bool_lit_opt()? {
432 return Ok(ProtobufConstant::Bool(b));
433 }
434
435 if let &Token::Symbol(c) = self.tokenizer.lookahead_some()? {
436 if c == '+' || c == '-' {
437 self.tokenizer.advance()?;
438 let sign = c == '+';
439 return Ok(self.next_num_lit()?.to_option_value(sign)?);
440 }
441 }
442
443 if let Some(r) = self.tokenizer.next_token_if_map(|token| match token {
444 &Token::StrLit(ref s) => Some(ProtobufConstant::String(s.clone())),
445 _ => None,
446 })? {
447 return Ok(r);
448 }
449
450 match self.tokenizer.lookahead_some()? {
451 &Token::IntLit(..) | &Token::FloatLit(..) => {
452 return self.next_num_lit()?.to_option_value(true);
453 }
454 &Token::Ident(..) => {
455 return Ok(ProtobufConstant::Ident(self.next_full_ident()?));
456 }
457 _ => {}
458 }
459
460 Err(ParserError::ExpectConstant.into())
461 }
462
463 fn next_field_value(&mut self) -> anyhow::Result<ProtobufConstant> {
464 if self.tokenizer.next_symbol_if_eq(':')? {
465 self.next_constant()
467 } else {
468 Ok(ProtobufConstant::Message(self.next_message_constant()?))
469 }
470 }
471
472 fn next_int_lit(&mut self) -> anyhow::Result<u64> {
473 self.tokenizer.next_token_check_map(|token| match token {
474 &Token::IntLit(i) => Ok(i),
475 _ => Err(ParserError::IncorrectInput.into()),
476 })
477 }
478
479 fn next_syntax(&mut self) -> anyhow::Result<Option<Syntax>> {
484 if self.tokenizer.next_ident_if_eq("syntax")? {
485 self.tokenizer.next_symbol_expect_eq('=', "syntax")?;
486 let syntax_str = self.tokenizer.next_str_lit()?.decode_utf8()?;
487 let syntax = if syntax_str == "proto2" {
488 Syntax::Proto2
489 } else if syntax_str == "proto3" {
490 Syntax::Proto3
491 } else {
492 return Err(ParserError::UnknownSyntax.into());
493 };
494 self.tokenizer.next_symbol_expect_eq(';', "syntax")?;
495 Ok(Some(syntax))
496 } else {
497 Ok(None)
498 }
499 }
500
501 fn next_import_opt(&mut self) -> anyhow::Result<Option<model::Import>> {
505 if self.tokenizer.next_ident_if_eq("import")? {
506 let vis = if self.tokenizer.next_ident_if_eq("weak")? {
507 ImportVis::Weak
508 } else if self.tokenizer.next_ident_if_eq("public")? {
509 ImportVis::Public
510 } else {
511 ImportVis::Default
512 };
513 let path = self.tokenizer.next_str_lit()?.decode_utf8()?;
514 self.tokenizer.next_symbol_expect_eq(';', "import")?;
515 let path = ProtoPathBuf::new(path)?;
516 Ok(Some(model::Import { path, vis }))
517 } else {
518 Ok(None)
519 }
520 }
521
522 fn next_package_opt(&mut self) -> anyhow::Result<Option<ProtobufAbsPath>> {
526 if self.tokenizer.next_ident_if_eq("package")? {
527 let package = self.next_full_ident_rel()?;
528 self.tokenizer.next_symbol_expect_eq(';', "package")?;
529 Ok(Some(package.into_absolute()))
530 } else {
531 Ok(None)
532 }
533 }
534
535 fn next_ident(&mut self) -> anyhow::Result<ProtobufIdent> {
538 Ok(ProtobufIdent::from(self.tokenizer.next_ident()?))
539 }
540
541 fn next_option_name_component(&mut self) -> anyhow::Result<ProtobufOptionNamePart> {
542 if self.tokenizer.next_symbol_if_eq('(')? {
543 let comp = self.next_full_ident()?;
544 self.tokenizer
545 .next_symbol_expect_eq(')', "option name component")?;
546 Ok(ProtobufOptionNamePart::Ext(comp))
547 } else {
548 Ok(ProtobufOptionNamePart::Direct(self.next_ident()?))
549 }
550 }
551
552 fn next_option_name(&mut self) -> anyhow::Result<ProtobufOptionName> {
555 let mut components = Vec::new();
556 components.push(self.next_option_name_component()?);
557 while self.tokenizer.next_symbol_if_eq('.')? {
558 components.push(self.next_option_name_component()?);
559 }
560 if components.len() == 1 {
561 if let ProtobufOptionNamePart::Direct(n) = &components[0] {
562 return Ok(ProtobufOptionName::Builtin(n.clone()));
563 }
564 }
565 Ok(ProtobufOptionName::Ext(ProtobufOptionNameExt(components)))
566 }
567
568 fn next_option_opt(&mut self) -> anyhow::Result<Option<ProtobufOption>> {
570 if self.tokenizer.next_ident_if_eq("option")? {
571 let name = self.next_option_name()?;
572 self.tokenizer.next_symbol_expect_eq('=', "option")?;
573 let value = self.next_constant()?;
574 self.tokenizer.next_symbol_expect_eq(';', "option")?;
575 Ok(Some(ProtobufOption { name, value }))
576 } else {
577 Ok(None)
578 }
579 }
580
581 fn next_label(&mut self, mode: MessageBodyParseMode) -> anyhow::Result<Option<Rule>> {
585 for rule in Rule::ALL {
586 let mut clone = self.clone();
587 if clone.tokenizer.next_ident_if_eq(rule.as_str())? {
588 if !mode.label_allowed(rule) {
589 return Err(ParserError::LabelNotAllowed.into());
590 }
591
592 *self = clone;
593 return Ok(Some(rule));
594 }
595 }
596
597 if mode.some_label_required() {
598 Err(ParserError::LabelRequired.into())
599 } else {
600 Ok(None)
601 }
602 }
603
604 fn next_field_type(&mut self) -> anyhow::Result<FieldType> {
605 let simple = &[
606 ("int32", FieldType::Int32),
607 ("int64", FieldType::Int64),
608 ("uint32", FieldType::Uint32),
609 ("uint64", FieldType::Uint64),
610 ("sint32", FieldType::Sint32),
611 ("sint64", FieldType::Sint64),
612 ("fixed32", FieldType::Fixed32),
613 ("sfixed32", FieldType::Sfixed32),
614 ("fixed64", FieldType::Fixed64),
615 ("sfixed64", FieldType::Sfixed64),
616 ("bool", FieldType::Bool),
617 ("string", FieldType::String),
618 ("bytes", FieldType::Bytes),
619 ("float", FieldType::Float),
620 ("double", FieldType::Double),
621 ];
622 for &(ref n, ref t) in simple {
623 if self.tokenizer.next_ident_if_eq(n)? {
624 return Ok(t.clone());
625 }
626 }
627
628 if let Some(t) = self.next_map_field_type_opt()? {
629 return Ok(t);
630 }
631
632 let message_or_enum = self.next_message_or_enum_type()?;
633 Ok(FieldType::MessageOrEnum(message_or_enum))
634 }
635
636 fn next_field_number(&mut self) -> anyhow::Result<i32> {
637 self.tokenizer.next_token_check_map(|token| match token {
639 &Token::IntLit(i) => i.to_i32(),
640 _ => Err(ParserError::IncorrectInput.into()),
641 })
642 }
643
644 fn next_field_option(&mut self) -> anyhow::Result<ProtobufOption> {
646 let name = self.next_option_name()?;
647 self.tokenizer.next_symbol_expect_eq('=', "field option")?;
648 let value = self.next_constant()?;
649 Ok(ProtobufOption { name, value })
650 }
651
652 fn next_field_options(&mut self) -> anyhow::Result<Vec<ProtobufOption>> {
654 let mut options = Vec::new();
655
656 options.push(self.next_field_option()?);
657
658 while self.tokenizer.next_symbol_if_eq(',')? {
659 options.push(self.next_field_option()?);
660 }
661
662 Ok(options)
663 }
664
665 fn next_field(&mut self, mode: MessageBodyParseMode) -> anyhow::Result<WithLoc<Field>> {
668 let loc = self.tokenizer.lookahead_loc();
669 let rule = if self.clone().tokenizer.next_ident_if_eq("map")? {
670 if !mode.map_allowed() {
671 return Err(ParserError::MapFieldNotAllowed.into());
672 }
673 None
674 } else {
675 self.next_label(mode)?
676 };
677 if self.tokenizer.next_ident_if_eq("group")? {
678 let name = self.next_group_name()?.to_owned();
679 self.tokenizer.next_symbol_expect_eq('=', "group")?;
680 let number = self.next_field_number()?;
681
682 let mode = match self.syntax {
683 Syntax::Proto2 => MessageBodyParseMode::MessageProto2,
684 Syntax::Proto3 => MessageBodyParseMode::MessageProto3,
685 };
686
687 let MessageBody { fields, .. } = self.next_message_body(mode)?;
688
689 let fields = fields
690 .into_iter()
691 .map(|fo| match fo.t {
692 FieldOrOneOf::Field(f) => Ok(f),
693 FieldOrOneOf::OneOf(_) => Err(ParserError::OneOfInGroup),
694 })
695 .collect::<Result<_, ParserError>>()?;
696
697 let field = Field {
698 name: name.to_ascii_lowercase(),
702 rule,
703 typ: FieldType::Group(Group { name, fields }),
704 number,
705 options: Vec::new(),
706 };
707 Ok(WithLoc { t: field, loc })
708 } else {
709 let typ = self.next_field_type()?;
710 let name = self.tokenizer.next_ident()?.to_owned();
711 self.tokenizer.next_symbol_expect_eq('=', "field")?;
712 let number = self.next_field_number()?;
713
714 let mut options = Vec::new();
715
716 if self.tokenizer.next_symbol_if_eq('[')? {
717 for o in self.next_field_options()? {
718 options.push(o);
719 }
720 self.tokenizer.next_symbol_expect_eq(']', "field")?;
721 }
722 self.tokenizer.next_symbol_expect_eq(';', "field")?;
723 let field = Field {
724 name,
725 rule,
726 typ,
727 number,
728 options,
729 };
730 Ok(WithLoc { t: field, loc })
731 }
732 }
733
734 fn next_oneof_opt(&mut self) -> anyhow::Result<Option<OneOf>> {
737 if self.tokenizer.next_ident_if_eq("oneof")? {
738 let name = self.tokenizer.next_ident()?.to_owned();
739 let MessageBody {
740 fields, options, ..
741 } = self.next_message_body(MessageBodyParseMode::Oneof)?;
742 let fields = fields
743 .into_iter()
744 .map(|fo| match fo.t {
745 FieldOrOneOf::Field(f) => Ok(f),
746 FieldOrOneOf::OneOf(_) => Err(ParserError::OneOfInOneOf),
747 })
748 .collect::<Result<_, ParserError>>()?;
749 Ok(Some(OneOf {
750 name,
751 fields,
752 options,
753 }))
754 } else {
755 Ok(None)
756 }
757 }
758
759 fn next_map_field_type_opt(&mut self) -> anyhow::Result<Option<FieldType>> {
763 if self.tokenizer.next_ident_if_eq("map")? {
764 self.tokenizer
765 .next_symbol_expect_eq('<', "map field type")?;
766 let key = self.next_field_type()?;
768 self.tokenizer
769 .next_symbol_expect_eq(',', "map field type")?;
770 let value = self.next_field_type()?;
771 self.tokenizer
772 .next_symbol_expect_eq('>', "map field type")?;
773 Ok(Some(FieldType::Map(Box::new((key, value)))))
774 } else {
775 Ok(None)
776 }
777 }
778
779 fn next_range(&mut self) -> anyhow::Result<RangeInclusive<i32>> {
785 let from = self.next_field_number()?;
786 let to = if self.tokenizer.next_ident_if_eq("to")? {
787 if self.tokenizer.next_ident_if_eq("max")? {
788 0x20000000 - 1
789 } else {
790 self.next_field_number()?
791 }
792 } else {
793 from
794 };
795 Ok(from..=to)
796 }
797
798 fn next_ranges(&mut self) -> anyhow::Result<Vec<RangeInclusive<i32>>> {
800 let mut ranges = Vec::new();
801 ranges.push(self.next_range()?);
802 while self.tokenizer.next_symbol_if_eq(',')? {
803 ranges.push(self.next_range()?);
804 }
805 Ok(ranges)
806 }
807
808 fn next_extensions_opt(&mut self) -> anyhow::Result<Option<Vec<RangeInclusive<i32>>>> {
810 if self.tokenizer.next_ident_if_eq("extensions")? {
811 Ok(Some(self.next_ranges()?))
812 } else {
813 Ok(None)
814 }
815 }
816
817 fn next_reserved_opt(
823 &mut self,
824 ) -> anyhow::Result<Option<(Vec<RangeInclusive<i32>>, Vec<String>)>> {
825 if self.tokenizer.next_ident_if_eq("reserved")? {
826 let (ranges, names) = if let &Token::StrLit(..) = self.tokenizer.lookahead_some()? {
827 let mut names = Vec::new();
828 names.push(self.tokenizer.next_str_lit()?.decode_utf8()?);
829 while self.tokenizer.next_symbol_if_eq(',')? {
830 names.push(self.tokenizer.next_str_lit()?.decode_utf8()?);
831 }
832 (Vec::new(), names)
833 } else {
834 (self.next_ranges()?, Vec::new())
835 };
836
837 self.tokenizer.next_symbol_expect_eq(';', "reserved")?;
838
839 Ok(Some((ranges, names)))
840 } else {
841 Ok(None)
842 }
843 }
844
845 fn next_enum_value_option(&mut self) -> anyhow::Result<ProtobufOption> {
851 let name = self.next_option_name()?;
852 self.tokenizer
853 .next_symbol_expect_eq('=', "enum value option")?;
854 let value = self.next_constant()?;
855 Ok(ProtobufOption { name, value })
856 }
857
858 fn next_enum_value(&mut self) -> anyhow::Result<i32> {
860 let minus = self.tokenizer.next_symbol_if_eq('-')?;
861 let lit = self.next_int_lit()?;
862 Ok(if minus {
863 let unsigned = lit.to_i64()?;
864 match unsigned.checked_neg() {
865 Some(neg) => neg.to_i32()?,
866 None => return Err(ParserError::IntegerOverflow.into()),
867 }
868 } else {
869 lit.to_i32()?
870 })
871 }
872
873 fn next_enum_field(&mut self) -> anyhow::Result<EnumValue> {
875 let name = self.tokenizer.next_ident()?.to_owned();
876 self.tokenizer.next_symbol_expect_eq('=', "enum field")?;
877 let number = self.next_enum_value()?;
878 let mut options = Vec::new();
879 if self.tokenizer.next_symbol_if_eq('[')? {
880 options.push(self.next_enum_value_option()?);
881 while self.tokenizer.next_symbol_if_eq(',')? {
882 options.push(self.next_enum_value_option()?);
883 }
884 self.tokenizer.next_symbol_expect_eq(']', "enum field")?;
885 }
886
887 Ok(EnumValue {
888 name,
889 number,
890 options,
891 })
892 }
893
894 fn next_enum_opt(&mut self) -> anyhow::Result<Option<WithLoc<Enumeration>>> {
897 let loc = self.tokenizer.lookahead_loc();
898
899 if self.tokenizer.next_ident_if_eq("enum")? {
900 let name = self.tokenizer.next_ident()?.to_owned();
901
902 let mut values = Vec::new();
903 let mut options = Vec::new();
904 let mut reserved_nums = Vec::new();
905 let mut reserved_names = Vec::new();
906
907 self.tokenizer.next_symbol_expect_eq('{', "enum")?;
908 while self.tokenizer.lookahead_if_symbol()? != Some('}') {
909 if self.tokenizer.next_symbol_if_eq(';')? {
911 continue;
912 }
913
914 if let Some((field_nums, field_names)) = self.next_reserved_opt()? {
915 reserved_nums.extend(field_nums);
916 reserved_names.extend(field_names);
917 continue;
918 }
919
920 if let Some(o) = self.next_option_opt()? {
921 options.push(o);
922 continue;
923 }
924
925 values.push(self.next_enum_field()?);
926 }
927 self.tokenizer.next_symbol_expect_eq('}', "enum")?;
928 let enumeration = Enumeration {
929 name,
930 values,
931 options,
932 reserved_nums,
933 reserved_names,
934 };
935 Ok(Some(WithLoc {
936 loc,
937 t: enumeration,
938 }))
939 } else {
940 Ok(None)
941 }
942 }
943
944 fn next_message_body(&mut self, mode: MessageBodyParseMode) -> anyhow::Result<MessageBody> {
949 self.tokenizer.next_symbol_expect_eq('{', "message body")?;
950
951 let mut r = MessageBody::default();
952
953 while self.tokenizer.lookahead_if_symbol()? != Some('}') {
954 let loc = self.tokenizer.lookahead_loc();
955
956 if self.tokenizer.next_symbol_if_eq(';')? {
958 continue;
959 }
960
961 if mode.is_most_non_fields_allowed() {
962 if let Some((field_nums, field_names)) = self.next_reserved_opt()? {
963 r.reserved_nums.extend(field_nums);
964 r.reserved_names.extend(field_names);
965 continue;
966 }
967
968 if let Some(oneof) = self.next_oneof_opt()? {
969 let one_of = FieldOrOneOf::OneOf(oneof);
970 r.fields.push(WithLoc { t: one_of, loc });
971 continue;
972 }
973
974 if let Some(extensions) = self.next_extend_opt()? {
975 r.extensions.extend(extensions);
976 continue;
977 }
978
979 if let Some(nested_message) = self.next_message_opt()? {
980 r.messages.push(nested_message);
981 continue;
982 }
983
984 if let Some(nested_enum) = self.next_enum_opt()? {
985 r.enums.push(nested_enum);
986 continue;
987 }
988 } else {
989 self.tokenizer.next_ident_if_eq_error("reserved")?;
990 self.tokenizer.next_ident_if_eq_error("oneof")?;
991 self.tokenizer.next_ident_if_eq_error("extend")?;
992 self.tokenizer.next_ident_if_eq_error("message")?;
993 self.tokenizer.next_ident_if_eq_error("enum")?;
994 }
995
996 if mode.is_extensions_allowed() {
997 if let Some(extension_ranges) = self.next_extensions_opt()? {
998 r.extension_ranges.extend(extension_ranges);
999 continue;
1000 }
1001 } else {
1002 self.tokenizer.next_ident_if_eq_error("extensions")?;
1003 }
1004
1005 if mode.is_option_allowed() {
1006 if let Some(option) = self.next_option_opt()? {
1007 r.options.push(option);
1008 continue;
1009 }
1010 } else {
1011 self.tokenizer.next_ident_if_eq_error("option")?;
1012 }
1013
1014 let field = FieldOrOneOf::Field(self.next_field(mode)?);
1015 r.fields.push(WithLoc { t: field, loc });
1016 }
1017
1018 self.tokenizer.next_symbol_expect_eq('}', "message body")?;
1019
1020 Ok(r)
1021 }
1022
1023 fn next_message_opt(&mut self) -> anyhow::Result<Option<WithLoc<Message>>> {
1025 let loc = self.tokenizer.lookahead_loc();
1026
1027 if self.tokenizer.next_ident_if_eq("message")? {
1028 let name = self.tokenizer.next_ident()?.to_owned();
1029
1030 let mode = match self.syntax {
1031 Syntax::Proto2 => MessageBodyParseMode::MessageProto2,
1032 Syntax::Proto3 => MessageBodyParseMode::MessageProto3,
1033 };
1034
1035 let MessageBody {
1036 fields,
1037 reserved_nums,
1038 reserved_names,
1039 messages,
1040 enums,
1041 options,
1042 extensions,
1043 extension_ranges,
1044 } = self.next_message_body(mode)?;
1045
1046 let message = Message {
1047 name,
1048 fields,
1049 reserved_nums,
1050 reserved_names,
1051 messages,
1052 enums,
1053 options,
1054 extensions,
1055 extension_ranges,
1056 };
1057 Ok(Some(WithLoc { t: message, loc }))
1058 } else {
1059 Ok(None)
1060 }
1061 }
1062
1063 fn next_extend_opt(&mut self) -> anyhow::Result<Option<Vec<WithLoc<Extension>>>> {
1067 let mut clone = self.clone();
1068 if clone.tokenizer.next_ident_if_eq("extend")? {
1069 *self = clone;
1073
1074 let extendee = self.next_message_or_enum_type()?;
1075
1076 let mode = match self.syntax {
1077 Syntax::Proto2 => MessageBodyParseMode::ExtendProto2,
1078 Syntax::Proto3 => MessageBodyParseMode::ExtendProto3,
1079 };
1080
1081 let MessageBody { fields, .. } = self.next_message_body(mode)?;
1082
1083 let fields: Vec<WithLoc<Field>> = fields
1085 .into_iter()
1086 .map(|fo| match fo.t {
1087 FieldOrOneOf::Field(f) => Ok(f),
1088 FieldOrOneOf::OneOf(_) => Err(ParserError::OneOfInExtend),
1089 })
1090 .collect::<Result<_, ParserError>>()?;
1091
1092 let extensions = fields
1093 .into_iter()
1094 .map(|field| {
1095 let extendee = extendee.clone();
1096 let loc = field.loc;
1097 let extension = Extension { extendee, field };
1098 WithLoc { t: extension, loc }
1099 })
1100 .collect();
1101
1102 Ok(Some(extensions))
1103 } else {
1104 Ok(None)
1105 }
1106 }
1107
1108 fn next_options_or_colon(&mut self) -> anyhow::Result<Vec<ProtobufOption>> {
1111 let mut options = Vec::new();
1112 if self.tokenizer.next_symbol_if_eq('{')? {
1113 while self.tokenizer.lookahead_if_symbol()? != Some('}') {
1114 if let Some(option) = self.next_option_opt()? {
1115 options.push(option);
1116 continue;
1117 }
1118
1119 if let Some(()) = self.next_empty_statement_opt()? {
1120 continue;
1121 }
1122
1123 return Err(ParserError::IncorrectInput.into());
1124 }
1125 self.tokenizer.next_symbol_expect_eq('}', "option")?;
1126 } else {
1127 self.tokenizer.next_symbol_expect_eq(';', "option")?;
1128 }
1129
1130 Ok(options)
1131 }
1132
1133 fn next_stream_opt(&mut self) -> anyhow::Result<Option<Method>> {
1136 assert_eq!(Syntax::Proto2, self.syntax);
1137 if self.tokenizer.next_ident_if_eq("stream")? {
1138 let name = self.tokenizer.next_ident()?;
1139 self.tokenizer.next_symbol_expect_eq('(', "stream")?;
1140 let input_type = self.next_message_or_enum_type()?;
1141 self.tokenizer.next_symbol_expect_eq(',', "stream")?;
1142 let output_type = self.next_message_or_enum_type()?;
1143 self.tokenizer.next_symbol_expect_eq(')', "stream")?;
1144 let options = self.next_options_or_colon()?;
1145 Ok(Some(Method {
1146 name,
1147 input_type,
1148 output_type,
1149 client_streaming: true,
1150 server_streaming: true,
1151 options,
1152 }))
1153 } else {
1154 Ok(None)
1155 }
1156 }
1157
1158 fn next_rpc_opt(&mut self) -> anyhow::Result<Option<Method>> {
1162 if self.tokenizer.next_ident_if_eq("rpc")? {
1163 let name = self.tokenizer.next_ident()?;
1164 self.tokenizer.next_symbol_expect_eq('(', "rpc")?;
1165 let client_streaming = self.tokenizer.next_ident_if_eq("stream")?;
1166 let input_type = self.next_message_or_enum_type()?;
1167 self.tokenizer.next_symbol_expect_eq(')', "rpc")?;
1168 self.tokenizer.next_ident_expect_eq("returns")?;
1169 self.tokenizer.next_symbol_expect_eq('(', "rpc")?;
1170 let server_streaming = self.tokenizer.next_ident_if_eq("stream")?;
1171 let output_type = self.next_message_or_enum_type()?;
1172 self.tokenizer.next_symbol_expect_eq(')', "rpc")?;
1173 let options = self.next_options_or_colon()?;
1174 Ok(Some(Method {
1175 name,
1176 input_type,
1177 output_type,
1178 client_streaming,
1179 server_streaming,
1180 options,
1181 }))
1182 } else {
1183 Ok(None)
1184 }
1185 }
1186
1187 fn next_service_opt(&mut self) -> anyhow::Result<Option<WithLoc<Service>>> {
1193 let loc = self.tokenizer.lookahead_loc();
1194
1195 if self.tokenizer.next_ident_if_eq("service")? {
1196 let name = self.tokenizer.next_ident()?;
1197 let mut methods = Vec::new();
1198 let mut options = Vec::new();
1199 self.tokenizer.next_symbol_expect_eq('{', "service")?;
1200 while self.tokenizer.lookahead_if_symbol()? != Some('}') {
1201 if let Some(method) = self.next_rpc_opt()? {
1202 methods.push(method);
1203 continue;
1204 }
1205
1206 if self.syntax == Syntax::Proto2 {
1207 if let Some(method) = self.next_stream_opt()? {
1208 methods.push(method);
1209 continue;
1210 }
1211 }
1212
1213 if let Some(o) = self.next_option_opt()? {
1214 options.push(o);
1215 continue;
1216 }
1217
1218 if let Some(()) = self.next_empty_statement_opt()? {
1219 continue;
1220 }
1221
1222 return Err(ParserError::IncorrectInput.into());
1223 }
1224 self.tokenizer.next_symbol_expect_eq('}', "service")?;
1225 Ok(Some(WithLoc {
1226 loc,
1227 t: Service {
1228 name,
1229 methods,
1230 options,
1231 },
1232 }))
1233 } else {
1234 Ok(None)
1235 }
1236 }
1237
1238 pub fn next_proto(&mut self) -> anyhow::Result<FileDescriptor> {
1243 let syntax = self.next_syntax()?.unwrap_or(Syntax::Proto2);
1244 self.syntax = syntax;
1245
1246 let mut imports = Vec::new();
1247 let mut package = ProtobufAbsPath::root();
1248 let mut messages = Vec::new();
1249 let mut enums = Vec::new();
1250 let mut extensions = Vec::new();
1251 let mut options = Vec::new();
1252 let mut services = Vec::new();
1253
1254 while !self.tokenizer.syntax_eof()? {
1255 if let Some(import) = self.next_import_opt()? {
1256 imports.push(import);
1257 continue;
1258 }
1259
1260 if let Some(next_package) = self.next_package_opt()? {
1261 package = next_package;
1262 continue;
1263 }
1264
1265 if let Some(option) = self.next_option_opt()? {
1266 options.push(option);
1267 continue;
1268 }
1269
1270 if let Some(message) = self.next_message_opt()? {
1271 messages.push(message);
1272 continue;
1273 }
1274
1275 if let Some(enumeration) = self.next_enum_opt()? {
1276 enums.push(enumeration);
1277 continue;
1278 }
1279
1280 if let Some(more_extensions) = self.next_extend_opt()? {
1281 extensions.extend(more_extensions);
1282 continue;
1283 }
1284
1285 if let Some(service) = self.next_service_opt()? {
1286 services.push(service);
1287 continue;
1288 }
1289
1290 if self.tokenizer.next_symbol_if_eq(';')? {
1291 continue;
1292 }
1293
1294 return Err(ParserError::IncorrectInput.into());
1295 }
1296
1297 Ok(FileDescriptor {
1298 imports,
1299 package,
1300 syntax,
1301 messages,
1302 enums,
1303 extensions,
1304 services,
1305 options,
1306 })
1307 }
1308}
1309
1310#[cfg(test)]
1311mod test {
1312 use super::*;
1313
1314 fn parse<P, R>(input: &str, parse_what: P) -> R
1315 where
1316 P: FnOnce(&mut Parser) -> anyhow::Result<R>,
1317 {
1318 let mut parser = Parser::new(input);
1319 let r =
1320 parse_what(&mut parser).expect(&format!("parse failed at {}", parser.tokenizer.loc()));
1321 let eof = parser
1322 .tokenizer
1323 .syntax_eof()
1324 .expect(&format!("check eof failed at {}", parser.tokenizer.loc()));
1325 assert!(eof, "{}", parser.tokenizer.loc());
1326 r
1327 }
1328
1329 fn parse_opt<P, R>(input: &str, parse_what: P) -> R
1330 where
1331 P: FnOnce(&mut Parser) -> anyhow::Result<Option<R>>,
1332 {
1333 let mut parser = Parser::new(input);
1334 let o =
1335 parse_what(&mut parser).expect(&format!("parse failed at {}", parser.tokenizer.loc()));
1336 let r = o.expect(&format!(
1337 "parser returned none at {}",
1338 parser.tokenizer.loc()
1339 ));
1340 assert!(parser.tokenizer.syntax_eof().unwrap());
1341 r
1342 }
1343
1344 #[test]
1345 fn test_syntax() {
1346 let msg = r#" syntax = "proto3"; "#;
1347 let mess = parse_opt(msg, |p| p.next_syntax());
1348 assert_eq!(Syntax::Proto3, mess);
1349 }
1350
1351 #[test]
1352 fn test_field_default_value_int() {
1353 let msg = r#" optional int64 f = 4 [default = 12]; "#;
1354 let mess = parse(msg, |p| p.next_field(MessageBodyParseMode::MessageProto2));
1355 assert_eq!("f", mess.t.name);
1356 assert_eq!(
1357 ProtobufOptionName::simple("default"),
1358 mess.t.options[0].name
1359 );
1360 assert_eq!("12", mess.t.options[0].value.format());
1361 }
1362
1363 #[test]
1364 fn test_field_default_value_float() {
1365 let msg = r#" optional float f = 2 [default = 10.0]; "#;
1366 let mess = parse(msg, |p| p.next_field(MessageBodyParseMode::MessageProto2));
1367 assert_eq!("f", mess.t.name);
1368 assert_eq!(
1369 ProtobufOptionName::simple("default"),
1370 mess.t.options[0].name
1371 );
1372 assert_eq!("10", mess.t.options[0].value.format());
1373 }
1374
1375 #[test]
1376 fn test_field_options() {
1377 let msg = r#" (my_opt).my_field = {foo: 1 bar: 2} "#;
1378 let opt = parse(msg, |p| p.next_field_option());
1379 assert_eq!(r#"{ foo: 1 bar: 2 }"#, opt.value.format());
1380
1381 let msg = r#" (my_opt).my_field = {foo: 1; bar:2;} "#;
1382 let opt = parse(msg, |p| p.next_field_option());
1383 assert_eq!(r#"{ foo: 1 bar: 2 }"#, opt.value.format());
1384
1385 let msg = r#" (my_opt).my_field = {foo: 1, bar: 2} "#;
1386 let opt = parse(msg, |p| p.next_field_option());
1387 assert_eq!(r#"{ foo: 1 bar: 2 }"#, opt.value.format());
1388
1389 let msg = r#" (my_opt).my_field = "foo" "#;
1390 let opt = parse(msg, |p| p.next_field_option());
1391 assert_eq!(r#""foo""#, opt.value.format());
1392
1393 let msg = r#" (my_opt) = { my_field: "foo"} "#;
1394 let opt = parse(msg, |p| p.next_field_option());
1395 assert_eq!(r#"{ my_field: "foo" }"#, opt.value.format());
1396
1397 let msg = r#" (my_opt) = { my_field: [] } "#;
1398 let opt = parse(msg, |p| p.next_field_option());
1399 assert_eq!(r#"{ my_field: [] }"#, opt.value.format());
1400
1401 let msg = r#" (my_opt) = { my_field: ["foo", "bar"] } "#;
1402 let opt = parse(msg, |p| p.next_field_option());
1403 assert_eq!(r#"{ my_field: ["foo","bar"] }"#, opt.value.format());
1404
1405 let msg = r#" (my_opt) = { my_field: [1, 2] } "#;
1406 let opt = parse(msg, |p| p.next_field_option());
1407 assert_eq!(r#"{ my_field: [1,2] }"#, opt.value.format());
1408 }
1409
1410 #[test]
1411 fn test_message() {
1412 let msg = r#"message ReferenceData
1413 {
1414 repeated ScenarioInfo scenarioSet = 1;
1415 repeated CalculatedObjectInfo calculatedObjectSet = 2;
1416 repeated RiskFactorList riskFactorListSet = 3;
1417 repeated RiskMaturityInfo riskMaturitySet = 4;
1418 repeated IndicatorInfo indicatorSet = 5;
1419 repeated RiskStrikeInfo riskStrikeSet = 6;
1420 repeated FreeProjectionList freeProjectionListSet = 7;
1421 repeated ValidationProperty ValidationSet = 8;
1422 repeated CalcProperties calcPropertiesSet = 9;
1423 repeated MaturityInfo maturitySet = 10;
1424 }"#;
1425
1426 let mess = parse_opt(msg, |p| p.next_message_opt());
1427 assert_eq!(10, mess.t.fields.len());
1428 }
1429
1430 #[test]
1431 fn test_enum() {
1432 let msg = r#"enum PairingStatus {
1433 DEALPAIRED = 0;
1434 INVENTORYORPHAN = 1;
1435 CALCULATEDORPHAN = 2;
1436 CANCELED = 3;
1437 }"#;
1438
1439 let enumeration = parse_opt(msg, |p| p.next_enum_opt());
1440 assert_eq!(4, enumeration.values.len());
1441 }
1442
1443 #[test]
1444 fn test_ignore() {
1445 let msg = r#"option optimize_for = SPEED;"#;
1446
1447 parse_opt(msg, |p| p.next_option_opt());
1448 }
1449
1450 #[test]
1451 fn test_import() {
1452 let msg = r#"syntax = "proto3";
1453
1454 import "test_import_nested_imported_pb.proto";
1455
1456 message ContainsImportedNested {
1457 ContainerForNested.NestedMessage m = 1;
1458 ContainerForNested.NestedEnum e = 2;
1459 }
1460 "#;
1461 let desc = parse(msg, |p| p.next_proto());
1462
1463 assert_eq!(
1464 vec!["test_import_nested_imported_pb.proto"],
1465 desc.imports
1466 .into_iter()
1467 .map(|i| i.path.to_str().to_owned())
1468 .collect::<Vec<_>>()
1469 );
1470 }
1471
1472 #[test]
1473 fn test_nested_message() {
1474 let msg = r#"message A
1475 {
1476 message B {
1477 repeated int32 a = 1;
1478 optional string b = 2;
1479 }
1480 optional string b = 1;
1481 }"#;
1482
1483 let mess = parse_opt(msg, |p| p.next_message_opt());
1484 assert_eq!(1, mess.t.messages.len());
1485 }
1486
1487 #[test]
1488 fn test_map() {
1489 let msg = r#"message A
1490 {
1491 optional map<string, int32> b = 1;
1492 }"#;
1493
1494 let mess = parse_opt(msg, |p| p.next_message_opt());
1495 assert_eq!(1, mess.t.fields.len());
1496 match mess.t.regular_fields_for_test()[0].typ {
1497 FieldType::Map(ref f) => match &**f {
1498 &(FieldType::String, FieldType::Int32) => (),
1499 ref f => panic!("Expecting Map<String, Int32> found {:?}", f),
1500 },
1501 ref f => panic!("Expecting map, got {:?}", f),
1502 }
1503 }
1504
1505 #[test]
1506 fn test_oneof() {
1507 let msg = r#"message A
1508 {
1509 optional int32 a1 = 1;
1510 oneof a_oneof {
1511 string a2 = 2;
1512 int32 a3 = 3;
1513 bytes a4 = 4;
1514 }
1515 repeated bool a5 = 5;
1516 }"#;
1517
1518 let mess = parse_opt(msg, |p| p.next_message_opt());
1519 assert_eq!(1, mess.t.oneofs().len());
1520 assert_eq!(3, mess.t.oneofs()[0].fields.len());
1521 }
1522
1523 #[test]
1524 fn test_reserved_in_message() {
1525 let msg = r#"message Sample {
1526 reserved 4, 15, 17 to 20, 30;
1527 reserved "foo", "bar";
1528 optional uint64 age =1;
1529 required bytes name =2;
1530 }"#;
1531
1532 let mess = parse_opt(msg, |p| p.next_message_opt());
1533 assert_eq!(
1534 vec![4..=4, 15..=15, 17..=20, 30..=30,],
1535 mess.t.reserved_nums
1536 );
1537 assert_eq!(
1538 vec!["foo".to_string(), "bar".to_string()],
1539 mess.t.reserved_names
1540 );
1541 assert_eq!(2, mess.t.fields.len());
1542 }
1543
1544 #[test]
1545 fn test_reserved_in_enum() {
1546 let msg = r#"enum Sample {
1547 reserved 4, 15, 17 to 20, 30;
1548 reserved "foo", "bar";
1549 }"#;
1550
1551 let enum_ = parse_opt(msg, |p| p.next_enum_opt());
1552 assert_eq!(
1553 vec![4..=4, 15..=15, 17..=20, 30..=30,],
1554 enum_.t.reserved_nums
1555 );
1556 assert_eq!(
1557 vec!["foo".to_string(), "bar".to_string()],
1558 enum_.t.reserved_names
1559 );
1560 }
1561
1562 #[test]
1563 fn test_default_value_int() {
1564 let msg = r#"message Sample {
1565 optional int32 x = 1 [default = 17];
1566 }"#;
1567
1568 let mess = parse_opt(msg, |p| p.next_message_opt());
1569 assert_eq!(
1570 ProtobufOptionName::simple("default"),
1571 mess.t.regular_fields_for_test()[0].options[0].name
1572 );
1573 assert_eq!(
1574 "17",
1575 mess.t.regular_fields_for_test()[0].options[0]
1576 .value
1577 .format()
1578 );
1579 }
1580
1581 #[test]
1582 fn test_default_value_string() {
1583 let msg = r#"message Sample {
1584 optional string x = 1 [default = "ab\nc d\"g\'h\0\"z"];
1585 }"#;
1586
1587 let mess = parse_opt(msg, |p| p.next_message_opt());
1588 assert_eq!(
1589 r#""ab\nc d\"g\'h\0\"z""#,
1590 mess.t.regular_fields_for_test()[0].options[0]
1591 .value
1592 .format()
1593 );
1594 }
1595
1596 #[test]
1597 fn test_default_value_bytes() {
1598 let msg = r#"message Sample {
1599 optional bytes x = 1 [default = "ab\nc d\xfeE\"g\'h\0\"z"];
1600 }"#;
1601
1602 let mess = parse_opt(msg, |p| p.next_message_opt());
1603 assert_eq!(
1604 r#""ab\nc d\xfeE\"g\'h\0\"z""#,
1605 mess.t.regular_fields_for_test()[0].options[0]
1606 .value
1607 .format()
1608 );
1609 }
1610
1611 #[test]
1612 fn test_group() {
1613 let msg = r#"message MessageWithGroup {
1614 optional string aaa = 1;
1615
1616 repeated group Identifier = 18 {
1617 optional int32 iii = 19;
1618 optional string sss = 20;
1619 }
1620
1621 required int bbb = 3;
1622 }"#;
1623 let mess = parse_opt(msg, |p| p.next_message_opt());
1624
1625 assert_eq!("identifier", mess.t.regular_fields_for_test()[1].name);
1626 if let FieldType::Group(Group { fields, .. }) = &mess.t.regular_fields_for_test()[1].typ {
1627 assert_eq!(2, fields.len());
1628 } else {
1629 panic!("expecting group");
1630 }
1631
1632 assert_eq!("bbb", mess.t.regular_fields_for_test()[2].name);
1633 }
1634
1635 #[test]
1636 fn test_incorrect_file_descriptor() {
1637 let msg = r#"
1638 message Foo {}
1639
1640 dfgdg
1641 "#;
1642
1643 let err = FileDescriptor::parse(msg).err().expect("err");
1644 assert_eq!(4, err.line);
1645 }
1646}