diff --git a/prost-build/src/ast.rs b/prost-build/src/ast.rs index 8a7fa2acd..7685a2e5a 100644 --- a/prost-build/src/ast.rs +++ b/prost-build/src/ast.rs @@ -5,7 +5,7 @@ use pulldown_cmark::{CodeBlockKind, Event, Options, Parser, Tag}; use regex::Regex; /// Comments on a Protobuf item. -#[derive(Debug, Clone)] +#[derive(Debug, Default, Clone)] pub struct Comments { /// Leading detached blocks of comments. pub leading_detached: Vec>, diff --git a/prost-build/src/code_generator.rs b/prost-build/src/code_generator.rs index 69a80ed3c..235b3da74 100644 --- a/prost-build/src/code_generator.rs +++ b/prost-build/src/code_generator.rs @@ -29,7 +29,7 @@ enum Syntax { pub struct CodeGenerator<'a> { config: &'a mut Config, package: String, - source_info: SourceCodeInfo, + source_info: Option, syntax: Syntax, message_graph: &'a MessageGraph, extern_paths: &'a ExternPaths, @@ -51,16 +51,14 @@ impl<'a> CodeGenerator<'a> { file: FileDescriptorProto, buf: &mut String, ) { - let mut source_info = file - .source_code_info - .expect("no source code info in request"); - source_info.location.retain(|location| { - let len = location.path.len(); - len > 0 && len % 2 == 0 + let source_info = file.source_code_info.map(|mut s| { + s.location.retain(|loc| { + let len = loc.path.len(); + len > 0 && len % 2 == 0 + }); + s.location.sort_by(|a, b| a.path.cmp(&b.path)); + s }); - source_info - .location - .sort_by_key(|location| location.path.clone()); let syntax = match file.syntax.as_ref().map(String::as_str) { None | Some("proto2") => Syntax::Proto2, @@ -569,14 +567,13 @@ impl<'a> CodeGenerator<'a> { self.buf.push_str("}\n"); } - fn location(&self) -> &Location { - let idx = self - .source_info + fn location(&self) -> Option<&Location> { + let source_info = self.source_info.as_ref()?; + let idx = source_info .location .binary_search_by_key(&&self.path[..], |location| &location.path[..]) .unwrap(); - - &self.source_info.location[idx] + Some(&source_info.location[idx]) } fn append_doc(&mut self, fq_name: &str, field_name: Option<&str>) { @@ -589,7 +586,9 @@ impl<'a> CodeGenerator<'a> { self.config.disable_comments.get(fq_name).next().is_none() }; if append_doc { - Comments::from_location(self.location()).append_with_indent(self.depth, self.buf) + if let Some(comments) = self.location().map(Comments::from_location) { + comments.append_with_indent(self.depth, self.buf); + } } } @@ -715,7 +714,7 @@ impl<'a> CodeGenerator<'a> { for variant in variant_mappings.iter() { self.push_indent(); - self.buf.push_str("\""); + self.buf.push('\"'); self.buf.push_str(variant.proto_name); self.buf.push_str("\" => Some(Self::"); self.buf.push_str(&variant.generated_variant_name); @@ -742,7 +741,10 @@ impl<'a> CodeGenerator<'a> { let name = service.name().to_owned(); debug!(" service: {:?}", name); - let comments = Comments::from_location(self.location()); + let comments = self + .location() + .map(Comments::from_location) + .unwrap_or_default(); self.path.push(2); let methods = service @@ -751,8 +753,12 @@ impl<'a> CodeGenerator<'a> { .enumerate() .map(|(idx, mut method)| { debug!(" method: {:?}", method.name()); + self.path.push(idx as i32); - let comments = Comments::from_location(self.location()); + let comments = self + .location() + .map(Comments::from_location) + .unwrap_or_default(); self.path.pop(); let name = method.name.take().unwrap(); diff --git a/prost-build/src/lib.rs b/prost-build/src/lib.rs index e8f51d0fc..34e509f63 100644 --- a/prost-build/src/lib.rs +++ b/prost-build/src/lib.rs @@ -664,8 +664,7 @@ impl Config { /// In combination with with `file_descriptor_set_path`, this can be used to provide a file /// descriptor set as an input file, rather than having prost-build generate the file by calling - /// protoc. Prost-build does require that the descriptor set was generated with - /// --include_source_info. + /// protoc. /// /// In `build.rs`: ///