olai_codegen/parsing/
mod.rs1use std::collections::HashMap;
2
3pub use self::http::{HttpPattern, UrlSegment, extract_http_rule_pattern, extract_path_parameters};
4pub use self::models::*;
5use protobuf::descriptor::{FileDescriptorProto, FileDescriptorSet, SourceCodeInfo};
6pub mod types;
7use crate::Result;
8
9mod enum_parser;
10pub mod http;
11mod message;
12mod models;
13mod service;
14
15pub(super) fn extract_documentation(sci: Option<&SourceCodeInfo>, path: &[i32]) -> Option<String> {
20 let sci = sci?;
21 for location in &sci.location {
22 if location.path.as_slice() == path {
23 let text = if location.has_leading_comments() {
24 location.leading_comments().trim().to_string()
25 } else if location.has_trailing_comments() {
26 location.trailing_comments().trim().to_string()
27 } else {
28 String::new()
29 };
30 if !text.is_empty() {
31 return Some(text);
32 }
33 }
34 }
35 None
36}
37
38const GOOGLE_API_HTTP_EXTENSION: u32 = 72295728; const GNOSTIC_OPERATION_EXTENSION: u32 = 1143; const GOOGLE_API_RESOURCE_EXTENSION: u32 = 1053; const GOOGLE_API_FIELD_BEHAVIOR_EXTENSION: u32 = 1052; const GOOGLE_API_RESOURCE_REFERENCE_EXTENSION: u32 = 1055; pub fn parse_file_descriptor_set(
46 file_descriptor_set: &FileDescriptorSet,
47) -> Result<CodeGenMetadata> {
48 let mut codegen_metadata = CodeGenMetadata {
49 messages: HashMap::new(),
50 enums: HashMap::new(),
51 services: HashMap::new(),
52 };
53
54 for file_descriptor in &file_descriptor_set.file {
56 process_file_descriptor(file_descriptor, &mut codegen_metadata)?;
57 }
58
59 Ok(codegen_metadata)
60}
61
62pub fn process_file_descriptor(
67 file_desc: &FileDescriptorProto,
68 codegen_metadata: &mut CodeGenMetadata,
69) -> Result<()> {
70 let file_name = file_desc.name();
71
72 let source_code_info = file_desc.source_code_info.as_ref();
74
75 for (enum_index, enum_desc) in file_desc.enum_type.iter().enumerate() {
77 let package_name = file_desc.package();
78 let type_prefix = if package_name.is_empty() {
79 String::new()
80 } else {
81 format!(".{}", package_name)
82 };
83 enum_parser::process_enum(
84 enum_desc,
85 codegen_metadata,
86 &type_prefix,
87 source_code_info,
88 &[5, enum_index as i32], )?;
90 }
91
92 for (message_index, message) in file_desc.message_type.iter().enumerate() {
94 let package_name = file_desc.package();
95 let type_prefix = if package_name.is_empty() {
96 String::new()
97 } else {
98 format!(".{}", package_name)
99 };
100
101 message::process_message(
102 message,
103 file_name,
104 codegen_metadata,
105 &type_prefix,
106 source_code_info,
107 &[4, message_index as i32], )?;
109 }
110
111 let package_name = file_desc.package().to_string();
113 for (service_index, service) in file_desc.service.iter().enumerate() {
114 service::process_service(
115 service,
116 &package_name,
117 codegen_metadata,
118 source_code_info,
119 service_index,
120 )?;
121 }
122
123 Ok(())
124}