use std::collections::HashMap;
pub use self::http::{HttpPattern, UrlSegment, extract_http_rule_pattern, extract_path_parameters};
pub use self::models::*;
use protobuf::descriptor::{FileDescriptorProto, FileDescriptorSet, SourceCodeInfo};
pub mod types;
use crate::Result;
mod enum_parser;
pub mod http;
mod message;
mod models;
mod service;
pub(super) fn extract_documentation(sci: Option<&SourceCodeInfo>, path: &[i32]) -> Option<String> {
let sci = sci?;
for location in &sci.location {
if location.path.as_slice() == path {
let text = if location.has_leading_comments() {
location.leading_comments().trim().to_string()
} else if location.has_trailing_comments() {
location.trailing_comments().trim().to_string()
} else {
String::new()
};
if !text.is_empty() {
return Some(text);
}
}
}
None
}
const 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(
file_descriptor_set: &FileDescriptorSet,
) -> Result<CodeGenMetadata> {
let mut codegen_metadata = CodeGenMetadata {
messages: HashMap::new(),
enums: HashMap::new(),
services: HashMap::new(),
};
for file_descriptor in &file_descriptor_set.file {
process_file_descriptor(file_descriptor, &mut codegen_metadata)?;
}
Ok(codegen_metadata)
}
pub fn process_file_descriptor(
file_desc: &FileDescriptorProto,
codegen_metadata: &mut CodeGenMetadata,
) -> Result<()> {
let file_name = file_desc.name();
let source_code_info = file_desc.source_code_info.as_ref();
for (enum_index, enum_desc) in file_desc.enum_type.iter().enumerate() {
let package_name = file_desc.package();
let type_prefix = if package_name.is_empty() {
String::new()
} else {
format!(".{}", package_name)
};
enum_parser::process_enum(
enum_desc,
codegen_metadata,
&type_prefix,
source_code_info,
&[5, enum_index as i32], )?;
}
for (message_index, message) in file_desc.message_type.iter().enumerate() {
let package_name = file_desc.package();
let type_prefix = if package_name.is_empty() {
String::new()
} else {
format!(".{}", package_name)
};
message::process_message(
message,
file_name,
codegen_metadata,
&type_prefix,
source_code_info,
&[4, message_index as i32], )?;
}
let package_name = file_desc.package().to_string();
for (service_index, service) in file_desc.service.iter().enumerate() {
service::process_service(
service,
&package_name,
codegen_metadata,
source_code_info,
service_index,
)?;
}
Ok(())
}