protobuf_parse/
parse_and_typecheck.rs

1use crate::ProtoPathBuf;
2
3/// Result of parsing `.proto` files.
4#[doc(hidden)]
5pub struct ParsedAndTypechecked {
6    /// One entry for each input `.proto` file.
7    pub relative_paths: Vec<ProtoPathBuf>,
8    /// All parsed `.proto` files including dependencies of input files.
9    pub file_descriptors: Vec<protobuf::descriptor::FileDescriptorProto>,
10    /// Description of the parser (e.g. to include in generated files).
11    pub parser: String,
12}
13
14#[cfg(test)]
15mod test {
16    use std::collections::HashSet;
17    use std::fs;
18
19    use crate::Parser;
20
21    #[test]
22    fn parse_and_typecheck() {
23        let dir = tempfile::tempdir().unwrap();
24        let a_proto = dir.path().join("a.proto");
25        let b_proto = dir.path().join("b.proto");
26        fs::write(&a_proto, "syntax = 'proto3'; message Apple {}").unwrap();
27        fs::write(
28            &b_proto,
29            "syntax = 'proto3'; import 'a.proto'; message Banana { Apple a = 1; }",
30        )
31        .unwrap();
32
33        let pure = Parser::new()
34            .pure()
35            .include(dir.path())
36            .input(&b_proto)
37            .parse_and_typecheck()
38            .unwrap();
39        let protoc = Parser::new()
40            .protoc()
41            .include(dir.path())
42            .input(&b_proto)
43            .parse_and_typecheck()
44            .unwrap();
45
46        assert_eq!(pure.relative_paths, protoc.relative_paths);
47        assert_eq!(2, pure.file_descriptors.len());
48        assert_eq!(2, protoc.file_descriptors.len());
49        // TODO: make result more deterministic
50        assert_eq!(
51            HashSet::from(["a.proto", "b.proto"]),
52            pure.file_descriptors.iter().map(|d| d.name()).collect()
53        );
54        assert_eq!(
55            HashSet::from(["a.proto", "b.proto"]),
56            protoc.file_descriptors.iter().map(|d| d.name()).collect()
57        );
58        assert_eq!(1, protoc.file_descriptors[0].message_type.len());
59        assert_eq!(1, pure.file_descriptors[0].message_type.len());
60        assert_eq!(
61            "Banana",
62            pure.file_descriptors
63                .iter()
64                .find(|d| d.name() == "b.proto")
65                .unwrap()
66                .message_type[0]
67                .name()
68        );
69        assert_eq!(
70            "Banana",
71            protoc
72                .file_descriptors
73                .iter()
74                .find(|d| d.name() == "b.proto")
75                .unwrap()
76                .message_type[0]
77                .name()
78        );
79    }
80}