From ed3dac935df0db5cedf5a3bcc566e703904d2ba6 Mon Sep 17 00:00:00 2001 From: David Freese Date: Sun, 18 Dec 2022 11:29:06 -0800 Subject: [PATCH 1/2] Allow file descriptor be generated without --include_source_info The file descriptor sets generated by rules_proto in bazel don't have this by default, so this allows some flexibility for users to reuse results that are already available to them. It's fairly trivial adjustment so it seemed reasonable to me to allow the flexibility. --- prost-build/src/ast.rs | 4 ++-- prost-build/src/code_generator.rs | 38 +++++++++++++++---------------- prost-build/src/lib.rs | 11 +++++---- 3 files changed, 28 insertions(+), 25 deletions(-) diff --git a/prost-build/src/ast.rs b/prost-build/src/ast.rs index 8a7fa2acd..53c8033fc 100644 --- a/prost-build/src/ast.rs +++ b/prost-build/src/ast.rs @@ -134,7 +134,7 @@ pub struct Service { /// The package name as it appears in the .proto file. pub package: String, /// The service comments. - pub comments: Comments, + pub comments: Option, /// The service methods. pub methods: Vec, /// The service options. @@ -149,7 +149,7 @@ pub struct Method { /// The name of the method as it appears in the .proto file. pub proto_name: String, /// The method comments. - pub comments: Comments, + pub comments: Option, /// The input Rust type. pub input_type: String, /// The output Rust type. diff --git a/prost-build/src/code_generator.rs b/prost-build/src/code_generator.rs index 69a80ed3c..488d9348b 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,7 @@ 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); self.path.push(2); let methods = service @@ -751,8 +750,9 @@ 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); 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..442988917 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`: /// @@ -1333,12 +1332,16 @@ mod tests { impl ServiceGenerator for ServiceTraitGenerator { fn generate(&mut self, service: Service, buf: &mut String) { // Generate a trait for the service. - service.comments.append_with_indent(0, buf); + if let Some(comments) = service.comments { + comments.append_with_indent(0, buf); + } buf.push_str(&format!("trait {} {{\n", &service.name)); // Generate the service methods. for method in service.methods { - method.comments.append_with_indent(1, buf); + if let Some(comments) = method.comments { + comments.append_with_indent(1, buf); + } buf.push_str(&format!( " fn {}(_: {}) -> {};\n", method.name, method.input_type, method.output_type From e1653f5e98cbe368ffa59e920b6b95dd643dde4a Mon Sep 17 00:00:00 2001 From: David Freese Date: Mon, 19 Dec 2022 11:48:16 -0800 Subject: [PATCH 2/2] revert breaking changes and add default --- prost-build/src/ast.rs | 6 +++--- prost-build/src/code_generator.rs | 10 ++++++++-- prost-build/src/lib.rs | 8 ++------ 3 files changed, 13 insertions(+), 11 deletions(-) diff --git a/prost-build/src/ast.rs b/prost-build/src/ast.rs index 53c8033fc..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>, @@ -134,7 +134,7 @@ pub struct Service { /// The package name as it appears in the .proto file. pub package: String, /// The service comments. - pub comments: Option, + pub comments: Comments, /// The service methods. pub methods: Vec, /// The service options. @@ -149,7 +149,7 @@ pub struct Method { /// The name of the method as it appears in the .proto file. pub proto_name: String, /// The method comments. - pub comments: Option, + pub comments: Comments, /// The input Rust type. pub input_type: String, /// The output Rust type. diff --git a/prost-build/src/code_generator.rs b/prost-build/src/code_generator.rs index 488d9348b..235b3da74 100644 --- a/prost-build/src/code_generator.rs +++ b/prost-build/src/code_generator.rs @@ -741,7 +741,10 @@ impl<'a> CodeGenerator<'a> { let name = service.name().to_owned(); debug!(" service: {:?}", name); - let comments = self.location().map(Comments::from_location); + let comments = self + .location() + .map(Comments::from_location) + .unwrap_or_default(); self.path.push(2); let methods = service @@ -752,7 +755,10 @@ impl<'a> CodeGenerator<'a> { debug!(" method: {:?}", method.name()); self.path.push(idx as i32); - let comments = self.location().map(Comments::from_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 442988917..34e509f63 100644 --- a/prost-build/src/lib.rs +++ b/prost-build/src/lib.rs @@ -1332,16 +1332,12 @@ mod tests { impl ServiceGenerator for ServiceTraitGenerator { fn generate(&mut self, service: Service, buf: &mut String) { // Generate a trait for the service. - if let Some(comments) = service.comments { - comments.append_with_indent(0, buf); - } + service.comments.append_with_indent(0, buf); buf.push_str(&format!("trait {} {{\n", &service.name)); // Generate the service methods. for method in service.methods { - if let Some(comments) = method.comments { - comments.append_with_indent(1, buf); - } + method.comments.append_with_indent(1, buf); buf.push_str(&format!( " fn {}(_: {}) -> {};\n", method.name, method.input_type, method.output_type