From 7e00810c59e31d8bf2514ea6771beee4e2445c20 Mon Sep 17 00:00:00 2001 From: Stepan Koltsov Date: Sun, 25 Feb 2024 20:43:17 +0000 Subject: [PATCH 01/21] Ignore error of flush in Drop of CodedOutputStream https://github.com/stepancheg/rust-protobuf/issues/714 --- protobuf/src/coded_output_stream/mod.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/protobuf/src/coded_output_stream/mod.rs b/protobuf/src/coded_output_stream/mod.rs index 5010df96f..26293399f 100644 --- a/protobuf/src/coded_output_stream/mod.rs +++ b/protobuf/src/coded_output_stream/mod.rs @@ -1010,8 +1010,9 @@ impl<'a> Write for CodedOutputStream<'a> { impl<'a> Drop for CodedOutputStream<'a> { fn drop(&mut self) { - // This may panic - CodedOutputStream::flush(self).expect("failed to flush"); + // User must call `flush` to guarantee that the data is written. + // Rust should have a lint to enforce `flush` call before drop. + let _ignore = CodedOutputStream::flush(self); } } From 232b8a9a70b7ef4d4af8282261f33d454e5d02f7 Mon Sep 17 00:00:00 2001 From: Stepan Koltsov Date: Sun, 25 Feb 2024 20:46:13 +0000 Subject: [PATCH 02/21] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 56cf71214..d413ef768 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ ## [3.4] - Unreleased * [Unnecessary copy in print_to_string_internal](https://github.com/stepancheg/rust-protobuf/pull/684) +* [Ignore error of `flush` in `Drop` of `CodedOutputStream`](https://github.com/stepancheg/rust-protobuf/issues/714) ## [3.3.0] - 2023-09-30 From 1e8e5ac45a2b716cf33cff053e33d18d054c23fb Mon Sep 17 00:00:00 2001 From: Stepan Koltsov Date: Sun, 25 Feb 2024 20:54:57 +0000 Subject: [PATCH 03/21] Remove some unused imports --- protobuf-support/src/lexer/lexer_impl.rs | 1 - protobuf/src/coded_input_stream/buf_read_iter.rs | 2 -- protobuf/src/message_field.rs | 1 - protobuf/src/reflect/field/mod.rs | 5 ----- 4 files changed, 9 deletions(-) diff --git a/protobuf-support/src/lexer/lexer_impl.rs b/protobuf-support/src/lexer/lexer_impl.rs index 4990c8f61..f0d6a9609 100644 --- a/protobuf-support/src/lexer/lexer_impl.rs +++ b/protobuf-support/src/lexer/lexer_impl.rs @@ -1,5 +1,4 @@ use std::char; -use std::convert::TryFrom; use std::num::ParseFloatError; use std::num::ParseIntError; diff --git a/protobuf/src/coded_input_stream/buf_read_iter.rs b/protobuf/src/coded_input_stream/buf_read_iter.rs index 94109f2d1..e79e22718 100644 --- a/protobuf/src/coded_input_stream/buf_read_iter.rs +++ b/protobuf/src/coded_input_stream/buf_read_iter.rs @@ -446,8 +446,6 @@ mod test_bytes { #[cfg(test)] mod test { use std::io; - use std::io::BufRead; - use std::io::Read; use super::*; diff --git a/protobuf/src/message_field.rs b/protobuf/src/message_field.rs index c7b46376e..5fc533178 100644 --- a/protobuf/src/message_field.rs +++ b/protobuf/src/message_field.rs @@ -1,4 +1,3 @@ -use std::default::Default; use std::hash::Hash; use std::ops::Deref; use std::option; diff --git a/protobuf/src/reflect/field/mod.rs b/protobuf/src/reflect/field/mod.rs index 3da38cad0..07c0ae8f6 100644 --- a/protobuf/src/reflect/field/mod.rs +++ b/protobuf/src/reflect/field/mod.rs @@ -563,12 +563,7 @@ pub(crate) enum FieldDescriptorImplRef<'a> { #[cfg(test)] mod test { - use std::collections::HashMap; - use crate::descriptor::DescriptorProto; - use crate::reflect::ReflectValueBox; - use crate::well_known_types::struct_::Struct; - use crate::well_known_types::struct_::Value; use crate::MessageFull; #[test] From 295398ebbf805e4dde4d101322afe2f8c4e4bf7d Mon Sep 17 00:00:00 2001 From: Levi Morrison Date: Sun, 25 Feb 2024 20:59:12 +0000 Subject: [PATCH 04/21] Faster encoded_varint64_len --- protobuf/src/varint/encode.rs | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/protobuf/src/varint/encode.rs b/protobuf/src/varint/encode.rs index eb9fc2d03..4d3e4ef67 100644 --- a/protobuf/src/varint/encode.rs +++ b/protobuf/src/varint/encode.rs @@ -92,12 +92,10 @@ pub(crate) fn encode_varint32(mut value: u32, buf: &mut [MaybeUninit]) -> us /// Encoded size of u64 value. #[inline] pub(crate) fn encoded_varint64_len(value: u64) -> usize { - if value == 0 { - 1 - } else { - let significant_bits = 64 - value.leading_zeros(); - (significant_bits + 6) as usize / 7 - } + // Bitwise-or'ing by 1 allows the `value = zero` case to work without + // affecting other cases. + let significant_bits = 64 - (value | 1).leading_zeros(); + (significant_bits + 6) as usize / 7 } #[cfg(test)] From 78ea5ef8b55fd7827ce1ad68679a74e0b5a96f7c Mon Sep 17 00:00:00 2001 From: Stepan Koltsov Date: Sun, 25 Feb 2024 21:02:05 +0000 Subject: [PATCH 05/21] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d413ef768..76f856f91 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ * [Unnecessary copy in print_to_string_internal](https://github.com/stepancheg/rust-protobuf/pull/684) * [Ignore error of `flush` in `Drop` of `CodedOutputStream`](https://github.com/stepancheg/rust-protobuf/issues/714) +* [Faster `encoded_varint64_len`](https://github.com/stepancheg/rust-protobuf/pull/709) ## [3.3.0] - 2023-09-30 From 42c8c7990d927ebcc5381388fbdc1dbd81bc3196 Mon Sep 17 00:00:00 2001 From: "Victor M. Alvarez" Date: Fri, 16 Feb 2024 17:14:24 +0100 Subject: [PATCH 06/21] Add support for `reserved` keyword in enums The `reserved` keyword was supported for messages but not for enums. Also, used this opportunity to remove the `FieldNumberRange` type and use `RangeInclusive` instead, as proposed by a `TODO` comment in the existing code. --- protobuf-parse/src/pure/convert/mod.rs | 21 ++++++++-- protobuf-parse/src/pure/model.rs | 20 ++++------ protobuf-parse/src/pure/parser.rs | 55 ++++++++++++++++++-------- 3 files changed, 63 insertions(+), 33 deletions(-) diff --git a/protobuf-parse/src/pure/convert/mod.rs b/protobuf-parse/src/pure/convert/mod.rs index c98fcf554..cae7fc06e 100644 --- a/protobuf-parse/src/pure/convert/mod.rs +++ b/protobuf-parse/src/pure/convert/mod.rs @@ -5,6 +5,7 @@ mod type_resolver; use protobuf; use protobuf::descriptor::descriptor_proto::ReservedRange; +use protobuf::descriptor::enum_descriptor_proto::EnumReservedRange; use protobuf::descriptor::field_descriptor_proto; use protobuf::descriptor::field_descriptor_proto::Type; use protobuf::descriptor::FieldDescriptorProto; @@ -296,8 +297,8 @@ impl<'a> Resolver<'a> { for ext in &input.extension_ranges { let mut extension_range = protobuf::descriptor::descriptor_proto::ExtensionRange::new(); - extension_range.set_start(ext.from); - extension_range.set_end(ext.to + 1); + extension_range.set_start(*ext.start()); + extension_range.set_end(*ext.end() + 1); output.extension_range.push(extension_range); } for ext in &input.extensions { @@ -313,8 +314,8 @@ impl<'a> Resolver<'a> { for reserved in &input.reserved_nums { let mut reserved_range = ReservedRange::new(); - reserved_range.set_start(reserved.from); - reserved_range.set_end(reserved.to + 1); + reserved_range.set_start(*reserved.start()); + reserved_range.set_end(*reserved.end() + 1); output.reserved_range.push(reserved_range); } output.reserved_name = input.reserved_names.clone().into(); @@ -526,6 +527,18 @@ impl<'a> Resolver<'a> { .iter() .map(|v| self.enum_value(scope, &v)) .collect::>()?; + + for reserved in &input.reserved_nums { + let mut reserved_range = EnumReservedRange::new(); + reserved_range.set_start(*reserved.start()); + // EnumReservedRange is inclusive, not like ExtensionRange and + // ReservedRange, which are exclusive. + reserved_range.set_end(*reserved.end()); + output.reserved_range.push(reserved_range); + } + + output.reserved_name = input.reserved_names.clone().into(); + Ok(output) } diff --git a/protobuf-parse/src/pure/model.rs b/protobuf-parse/src/pure/model.rs index 3efdc1136..8e2cb5fa9 100644 --- a/protobuf-parse/src/pure/model.rs +++ b/protobuf-parse/src/pure/model.rs @@ -6,6 +6,7 @@ use std::fmt; use std::fmt::Write; use std::ops::Deref; +use std::ops::RangeInclusive; use indexmap::IndexMap; use protobuf::reflect::ReflectValueBox; @@ -213,15 +214,6 @@ pub(crate) enum FieldOrOneOf { OneOf(OneOf), } -/// Extension range -#[derive(Default, Debug, Eq, PartialEq, Copy, Clone)] -pub(crate) struct FieldNumberRange { - /// First number - pub from: i32, - /// Inclusive - pub to: i32, -} - /// A protobuf message #[derive(Debug, Clone, Default)] pub(crate) struct Message { @@ -230,9 +222,7 @@ pub(crate) struct Message { /// Message fields and oneofs pub fields: Vec>, /// Message reserved numbers - /// - /// TODO: use RangeInclusive once stable - pub reserved_nums: Vec, + pub reserved_nums: Vec>, /// Message reserved names pub reserved_names: Vec, /// Nested messages @@ -242,7 +232,7 @@ pub(crate) struct Message { /// Non-builtin options pub options: Vec, /// Extension field numbers - pub extension_ranges: Vec, + pub extension_ranges: Vec>, /// Extensions pub extensions: Vec>, } @@ -318,6 +308,10 @@ pub(crate) struct Enumeration { pub values: Vec, /// enum options pub options: Vec, + /// enum reserved numbers + pub reserved_nums: Vec>, + /// enum reserved names + pub reserved_names: Vec, } /// A OneOf diff --git a/protobuf-parse/src/pure/parser.rs b/protobuf-parse/src/pure/parser.rs index 1c40f406f..27cdb6fec 100644 --- a/protobuf-parse/src/pure/parser.rs +++ b/protobuf-parse/src/pure/parser.rs @@ -1,3 +1,4 @@ +use std::ops::RangeInclusive; use std::str; use protobuf_support::lexer::int; @@ -21,7 +22,6 @@ use crate::pure::model::EnumValue; use crate::pure::model::Enumeration; use crate::pure::model::Extension; use crate::pure::model::Field; -use crate::pure::model::FieldNumberRange; use crate::pure::model::FieldOrOneOf; use crate::pure::model::FieldType; use crate::pure::model::FileDescriptor; @@ -264,12 +264,12 @@ impl MessageBodyParseMode { #[derive(Default)] pub(crate) struct MessageBody { pub fields: Vec>, - pub reserved_nums: Vec, + pub reserved_nums: Vec>, pub reserved_names: Vec, pub messages: Vec>, pub enums: Vec>, pub options: Vec, - pub extension_ranges: Vec, + pub extension_ranges: Vec>, pub extensions: Vec>, } @@ -775,7 +775,7 @@ impl<'a> Parser<'a> { // Extensions // range = intLit [ "to" ( intLit | "max" ) ] - fn next_range(&mut self) -> anyhow::Result { + fn next_range(&mut self) -> anyhow::Result> { let from = self.next_field_number()?; let to = if self.tokenizer.next_ident_if_eq("to")? { if self.tokenizer.next_ident_if_eq("max")? { @@ -786,11 +786,11 @@ impl<'a> Parser<'a> { } else { from }; - Ok(FieldNumberRange { from, to }) + Ok(from..=to) } // ranges = range { "," range } - fn next_ranges(&mut self) -> anyhow::Result> { + fn next_ranges(&mut self) -> anyhow::Result>> { let mut ranges = Vec::new(); ranges.push(self.next_range()?); while self.tokenizer.next_symbol_if_eq(',')? { @@ -800,7 +800,7 @@ impl<'a> Parser<'a> { } // extensions = "extensions" ranges ";" - fn next_extensions_opt(&mut self) -> anyhow::Result>> { + fn next_extensions_opt(&mut self) -> anyhow::Result>>> { if self.tokenizer.next_ident_if_eq("extensions")? { Ok(Some(self.next_ranges()?)) } else { @@ -815,7 +815,7 @@ impl<'a> Parser<'a> { // fieldNames = fieldName { "," fieldName } fn next_reserved_opt( &mut self, - ) -> anyhow::Result, Vec)>> { + ) -> anyhow::Result>, Vec)>> { if self.tokenizer.next_ident_if_eq("reserved")? { let (ranges, names) = if let &Token::StrLit(..) = self.tokenizer.lookahead_some()? { let mut names = Vec::new(); @@ -886,7 +886,7 @@ impl<'a> Parser<'a> { } // enum = "enum" enumName enumBody - // enumBody = "{" { option | enumField | emptyStatement } "}" + // enumBody = "{" { option | enumField | emptyStatement | reserved } "}" fn next_enum_opt(&mut self) -> anyhow::Result>> { let loc = self.tokenizer.lookahead_loc(); @@ -895,6 +895,8 @@ impl<'a> Parser<'a> { let mut values = Vec::new(); let mut options = Vec::new(); + let mut reserved_nums = Vec::new(); + let mut reserved_names = Vec::new(); self.tokenizer.next_symbol_expect_eq('{', "enum")?; while self.tokenizer.lookahead_if_symbol()? != Some('}') { @@ -903,6 +905,12 @@ impl<'a> Parser<'a> { continue; } + if let Some((field_nums, field_names)) = self.next_reserved_opt()? { + reserved_nums.extend(field_nums); + reserved_names.extend(field_names); + continue; + } + if let Some(o) = self.next_option_opt()? { options.push(o); continue; @@ -915,6 +923,8 @@ impl<'a> Parser<'a> { name, values, options, + reserved_nums, + reserved_names, }; Ok(Some(WithLoc { loc, @@ -1470,7 +1480,7 @@ mod test { } #[test] - fn test_reserved() { + fn test_reserved_in_message() { let msg = r#"message Sample { reserved 4, 15, 17 to 20, 30; reserved "foo", "bar"; @@ -1480,12 +1490,7 @@ mod test { let mess = parse_opt(msg, |p| p.next_message_opt()); assert_eq!( - vec![ - FieldNumberRange { from: 4, to: 4 }, - FieldNumberRange { from: 15, to: 15 }, - FieldNumberRange { from: 17, to: 20 }, - FieldNumberRange { from: 30, to: 30 } - ], + vec![4..=4, 15..=15, 17..=20, 30..=30,], mess.t.reserved_nums ); assert_eq!( @@ -1495,6 +1500,24 @@ mod test { assert_eq!(2, mess.t.fields.len()); } + #[test] + fn test_reserved_in_enum() { + let msg = r#"enum Sample { + reserved 4, 15, 17 to 20, 30; + reserved "foo", "bar"; + }"#; + + let enum_ = parse_opt(msg, |p| p.next_enum_opt()); + assert_eq!( + vec![4..=4, 15..=15, 17..=20, 30..=30,], + enum_.t.reserved_nums + ); + assert_eq!( + vec!["foo".to_string(), "bar".to_string()], + enum_.t.reserved_names + ); + } + #[test] fn test_default_value_int() { let msg = r#"message Sample { From 4df4d77220d890c6225e08c18aec7a14863c5055 Mon Sep 17 00:00:00 2001 From: Stepan Koltsov Date: Sun, 25 Feb 2024 21:08:32 +0000 Subject: [PATCH 07/21] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 76f856f91..d4410cfdb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ * [Unnecessary copy in print_to_string_internal](https://github.com/stepancheg/rust-protobuf/pull/684) * [Ignore error of `flush` in `Drop` of `CodedOutputStream`](https://github.com/stepancheg/rust-protobuf/issues/714) * [Faster `encoded_varint64_len`](https://github.com/stepancheg/rust-protobuf/pull/709) +* [`reserved` keyword in enums](https://github.com/stepancheg/rust-protobuf/pull/712) ## [3.3.0] - 2023-09-30 From 50e40ed9fa7d6238b183d65fc279571ba915f1fb Mon Sep 17 00:00:00 2001 From: Stepan Koltsov Date: Sun, 25 Feb 2024 21:09:58 +0000 Subject: [PATCH 08/21] Remove some unused imports --- protobuf-parse/src/pure/convert/mod.rs | 1 - test-crates/protobuf-test-common/src/build.rs | 1 - test-crates/protobuf-test-common/src/text_format_tests.rs | 1 - 3 files changed, 3 deletions(-) diff --git a/protobuf-parse/src/pure/convert/mod.rs b/protobuf-parse/src/pure/convert/mod.rs index cae7fc06e..3bb63f2f2 100644 --- a/protobuf-parse/src/pure/convert/mod.rs +++ b/protobuf-parse/src/pure/convert/mod.rs @@ -3,7 +3,6 @@ mod option_resolver; mod type_resolver; -use protobuf; use protobuf::descriptor::descriptor_proto::ReservedRange; use protobuf::descriptor::enum_descriptor_proto::EnumReservedRange; use protobuf::descriptor::field_descriptor_proto; diff --git a/test-crates/protobuf-test-common/src/build.rs b/test-crates/protobuf-test-common/src/build.rs index 6e013b7da..ae35d07bf 100644 --- a/test-crates/protobuf-test-common/src/build.rs +++ b/test-crates/protobuf-test-common/src/build.rs @@ -8,7 +8,6 @@ use std::io::Write; use std::path::Path; use anyhow::Context; -use glob; use log::debug; pub use protobuf_codegen::Customize; diff --git a/test-crates/protobuf-test-common/src/text_format_tests.rs b/test-crates/protobuf-test-common/src/text_format_tests.rs index cf67d8d5e..347e36d10 100644 --- a/test-crates/protobuf-test-common/src/text_format_tests.rs +++ b/test-crates/protobuf-test-common/src/text_format_tests.rs @@ -13,7 +13,6 @@ use protobuf::text_format::merge_from_str; use protobuf::text_format::print_to_string; use protobuf::Message; use protobuf::MessageDyn; -use tempfile; pub fn parse_using_rust_protobuf( text: &str, From 0e3bf94728b7d9126144e31b507477bdaa4004e0 Mon Sep 17 00:00:00 2001 From: Ryan Roden-Corrent Date: Tue, 16 Jan 2024 08:41:33 -0500 Subject: [PATCH 09/21] Default to packed repeated primitive fields in proto3. Fixes #704. In proto3, repeated primitive fields should be packed by default: https://protobuf.dev/programming-guides/encoding/#packed --- protobuf-codegen/src/gen/field/mod.rs | 31 ++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/protobuf-codegen/src/gen/field/mod.rs b/protobuf-codegen/src/gen/field/mod.rs index d6a5e44a4..79a16e05e 100644 --- a/protobuf-codegen/src/gen/field/mod.rs +++ b/protobuf-codegen/src/gen/field/mod.rs @@ -188,7 +188,36 @@ impl<'a> FieldGen<'a> { FieldKind::Repeated(RepeatedField { elem, - packed: field.field.proto().options.get_or_default().packed(), + packed: field + .field + .proto() + .options + .get_or_default() + .packed + .unwrap_or(match field.message.scope.file_scope.syntax() { + Syntax::Proto2 => false, + // in proto3, repeated primitive types are packed by default + Syntax::Proto3 => match field.field.proto().type_() { + Type::TYPE_DOUBLE + | Type::TYPE_FLOAT + | Type::TYPE_INT64 + | Type::TYPE_UINT64 + | Type::TYPE_INT32 + | Type::TYPE_FIXED64 + | Type::TYPE_FIXED32 + | Type::TYPE_BOOL + | Type::TYPE_UINT32 + | Type::TYPE_SFIXED32 + | Type::TYPE_SFIXED64 + | Type::TYPE_SINT32 + | Type::TYPE_SINT64 => true, + Type::TYPE_STRING + | Type::TYPE_GROUP + | Type::TYPE_MESSAGE + | Type::TYPE_BYTES + | Type::TYPE_ENUM => false, + }, + }), }) } RuntimeFieldType::Singular(..) => { From 167c58e09bff7fbee2d27cbe0cfa3c252e5cbbe9 Mon Sep 17 00:00:00 2001 From: Ryan Roden-Corrent Date: Wed, 17 Jan 2024 08:10:40 -0500 Subject: [PATCH 10/21] Provide a better error on a packed non-primitive. Fixes #706. --- protobuf-codegen/src/gen/field/mod.rs | 71 ++++++++++++++------------- 1 file changed, 37 insertions(+), 34 deletions(-) diff --git a/protobuf-codegen/src/gen/field/mod.rs b/protobuf-codegen/src/gen/field/mod.rs index 79a16e05e..54e17b843 100644 --- a/protobuf-codegen/src/gen/field/mod.rs +++ b/protobuf-codegen/src/gen/field/mod.rs @@ -185,40 +185,43 @@ impl<'a> FieldGen<'a> { } RuntimeFieldType::Repeated(..) => { let elem = field_elem(&field, root_scope, &customize); - - FieldKind::Repeated(RepeatedField { - elem, - packed: field - .field - .proto() - .options - .get_or_default() - .packed - .unwrap_or(match field.message.scope.file_scope.syntax() { - Syntax::Proto2 => false, - // in proto3, repeated primitive types are packed by default - Syntax::Proto3 => match field.field.proto().type_() { - Type::TYPE_DOUBLE - | Type::TYPE_FLOAT - | Type::TYPE_INT64 - | Type::TYPE_UINT64 - | Type::TYPE_INT32 - | Type::TYPE_FIXED64 - | Type::TYPE_FIXED32 - | Type::TYPE_BOOL - | Type::TYPE_UINT32 - | Type::TYPE_SFIXED32 - | Type::TYPE_SFIXED64 - | Type::TYPE_SINT32 - | Type::TYPE_SINT64 => true, - Type::TYPE_STRING - | Type::TYPE_GROUP - | Type::TYPE_MESSAGE - | Type::TYPE_BYTES - | Type::TYPE_ENUM => false, - }, - }), - }) + let primitive = match field.field.proto().type_() { + Type::TYPE_DOUBLE + | Type::TYPE_FLOAT + | Type::TYPE_INT64 + | Type::TYPE_UINT64 + | Type::TYPE_INT32 + | Type::TYPE_FIXED64 + | Type::TYPE_FIXED32 + | Type::TYPE_BOOL + | Type::TYPE_UINT32 + | Type::TYPE_SFIXED32 + | Type::TYPE_SFIXED64 + | Type::TYPE_SINT32 + | Type::TYPE_SINT64 => true, + Type::TYPE_STRING + | Type::TYPE_GROUP + | Type::TYPE_MESSAGE + | Type::TYPE_BYTES + | Type::TYPE_ENUM => false, + }; + let packed = field + .field + .proto() + .options + .get_or_default() + .packed + .unwrap_or(match field.message.scope.file_scope.syntax() { + Syntax::Proto2 => false, + // in proto3, repeated primitive types are packed by default + Syntax::Proto3 => primitive, + }); + if packed && !primitive { + anyhow::bail!( + "[packed = true] can only be specified for repeated primitive fields" + ); + } + FieldKind::Repeated(RepeatedField { elem, packed }) } RuntimeFieldType::Singular(..) => { let elem = field_elem(&field, root_scope, &customize); From 6d92003632f5abc55325bbef448b2aaa6169042d Mon Sep 17 00:00:00 2001 From: Ryan Roden-Corrent Date: Thu, 18 Jan 2024 07:46:21 -0500 Subject: [PATCH 11/21] Treat enums as primitive. --- protobuf-codegen/src/gen/field/mod.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/protobuf-codegen/src/gen/field/mod.rs b/protobuf-codegen/src/gen/field/mod.rs index 54e17b843..ac9617289 100644 --- a/protobuf-codegen/src/gen/field/mod.rs +++ b/protobuf-codegen/src/gen/field/mod.rs @@ -198,12 +198,12 @@ impl<'a> FieldGen<'a> { | Type::TYPE_SFIXED32 | Type::TYPE_SFIXED64 | Type::TYPE_SINT32 - | Type::TYPE_SINT64 => true, + | Type::TYPE_SINT64 + | Type::TYPE_ENUM => true, Type::TYPE_STRING | Type::TYPE_GROUP | Type::TYPE_MESSAGE - | Type::TYPE_BYTES - | Type::TYPE_ENUM => false, + | Type::TYPE_BYTES => false, }; let packed = field .field From 364161fd83fe8d621ab31098174a65e4a097cf24 Mon Sep 17 00:00:00 2001 From: Stepan Koltsov Date: Sun, 25 Feb 2024 21:20:17 +0000 Subject: [PATCH 12/21] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d4410cfdb..b847adea1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ * [Ignore error of `flush` in `Drop` of `CodedOutputStream`](https://github.com/stepancheg/rust-protobuf/issues/714) * [Faster `encoded_varint64_len`](https://github.com/stepancheg/rust-protobuf/pull/709) * [`reserved` keyword in enums](https://github.com/stepancheg/rust-protobuf/pull/712) +* [repeated primitives are packed by default in proto3](https://github.com/stepancheg/rust-protobuf/pull/707) ## [3.3.0] - 2023-09-30 From 5dfba8bee5af0172e094e1378b273f0a3a97fa96 Mon Sep 17 00:00:00 2001 From: Stepan Koltsov Date: Sun, 25 Feb 2024 21:22:20 +0000 Subject: [PATCH 13/21] Revert "Treat enums as primitive." This reverts commit 6d92003632f5abc55325bbef448b2aaa6169042d. --- protobuf-codegen/src/gen/field/mod.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/protobuf-codegen/src/gen/field/mod.rs b/protobuf-codegen/src/gen/field/mod.rs index ac9617289..54e17b843 100644 --- a/protobuf-codegen/src/gen/field/mod.rs +++ b/protobuf-codegen/src/gen/field/mod.rs @@ -198,12 +198,12 @@ impl<'a> FieldGen<'a> { | Type::TYPE_SFIXED32 | Type::TYPE_SFIXED64 | Type::TYPE_SINT32 - | Type::TYPE_SINT64 - | Type::TYPE_ENUM => true, + | Type::TYPE_SINT64 => true, Type::TYPE_STRING | Type::TYPE_GROUP | Type::TYPE_MESSAGE - | Type::TYPE_BYTES => false, + | Type::TYPE_BYTES + | Type::TYPE_ENUM => false, }; let packed = field .field From 869670a7ab5688391975bc7add90bcb5693a1ff3 Mon Sep 17 00:00:00 2001 From: Stepan Koltsov Date: Sun, 25 Feb 2024 21:22:25 +0000 Subject: [PATCH 14/21] Revert "Provide a better error on a packed non-primitive." This reverts commit 167c58e09bff7fbee2d27cbe0cfa3c252e5cbbe9. --- protobuf-codegen/src/gen/field/mod.rs | 71 +++++++++++++-------------- 1 file changed, 34 insertions(+), 37 deletions(-) diff --git a/protobuf-codegen/src/gen/field/mod.rs b/protobuf-codegen/src/gen/field/mod.rs index 54e17b843..79a16e05e 100644 --- a/protobuf-codegen/src/gen/field/mod.rs +++ b/protobuf-codegen/src/gen/field/mod.rs @@ -185,43 +185,40 @@ impl<'a> FieldGen<'a> { } RuntimeFieldType::Repeated(..) => { let elem = field_elem(&field, root_scope, &customize); - let primitive = match field.field.proto().type_() { - Type::TYPE_DOUBLE - | Type::TYPE_FLOAT - | Type::TYPE_INT64 - | Type::TYPE_UINT64 - | Type::TYPE_INT32 - | Type::TYPE_FIXED64 - | Type::TYPE_FIXED32 - | Type::TYPE_BOOL - | Type::TYPE_UINT32 - | Type::TYPE_SFIXED32 - | Type::TYPE_SFIXED64 - | Type::TYPE_SINT32 - | Type::TYPE_SINT64 => true, - Type::TYPE_STRING - | Type::TYPE_GROUP - | Type::TYPE_MESSAGE - | Type::TYPE_BYTES - | Type::TYPE_ENUM => false, - }; - let packed = field - .field - .proto() - .options - .get_or_default() - .packed - .unwrap_or(match field.message.scope.file_scope.syntax() { - Syntax::Proto2 => false, - // in proto3, repeated primitive types are packed by default - Syntax::Proto3 => primitive, - }); - if packed && !primitive { - anyhow::bail!( - "[packed = true] can only be specified for repeated primitive fields" - ); - } - FieldKind::Repeated(RepeatedField { elem, packed }) + + FieldKind::Repeated(RepeatedField { + elem, + packed: field + .field + .proto() + .options + .get_or_default() + .packed + .unwrap_or(match field.message.scope.file_scope.syntax() { + Syntax::Proto2 => false, + // in proto3, repeated primitive types are packed by default + Syntax::Proto3 => match field.field.proto().type_() { + Type::TYPE_DOUBLE + | Type::TYPE_FLOAT + | Type::TYPE_INT64 + | Type::TYPE_UINT64 + | Type::TYPE_INT32 + | Type::TYPE_FIXED64 + | Type::TYPE_FIXED32 + | Type::TYPE_BOOL + | Type::TYPE_UINT32 + | Type::TYPE_SFIXED32 + | Type::TYPE_SFIXED64 + | Type::TYPE_SINT32 + | Type::TYPE_SINT64 => true, + Type::TYPE_STRING + | Type::TYPE_GROUP + | Type::TYPE_MESSAGE + | Type::TYPE_BYTES + | Type::TYPE_ENUM => false, + }, + }), + }) } RuntimeFieldType::Singular(..) => { let elem = field_elem(&field, root_scope, &customize); From 3b8d84e66756a6e7fc49cfa4025cef0f84b566ce Mon Sep 17 00:00:00 2001 From: Stepan Koltsov Date: Sun, 25 Feb 2024 21:22:30 +0000 Subject: [PATCH 15/21] Revert "Default to packed repeated primitive fields in proto3." This reverts commit 0e3bf94728b7d9126144e31b507477bdaa4004e0. --- protobuf-codegen/src/gen/field/mod.rs | 31 +-------------------------- 1 file changed, 1 insertion(+), 30 deletions(-) diff --git a/protobuf-codegen/src/gen/field/mod.rs b/protobuf-codegen/src/gen/field/mod.rs index 79a16e05e..d6a5e44a4 100644 --- a/protobuf-codegen/src/gen/field/mod.rs +++ b/protobuf-codegen/src/gen/field/mod.rs @@ -188,36 +188,7 @@ impl<'a> FieldGen<'a> { FieldKind::Repeated(RepeatedField { elem, - packed: field - .field - .proto() - .options - .get_or_default() - .packed - .unwrap_or(match field.message.scope.file_scope.syntax() { - Syntax::Proto2 => false, - // in proto3, repeated primitive types are packed by default - Syntax::Proto3 => match field.field.proto().type_() { - Type::TYPE_DOUBLE - | Type::TYPE_FLOAT - | Type::TYPE_INT64 - | Type::TYPE_UINT64 - | Type::TYPE_INT32 - | Type::TYPE_FIXED64 - | Type::TYPE_FIXED32 - | Type::TYPE_BOOL - | Type::TYPE_UINT32 - | Type::TYPE_SFIXED32 - | Type::TYPE_SFIXED64 - | Type::TYPE_SINT32 - | Type::TYPE_SINT64 => true, - Type::TYPE_STRING - | Type::TYPE_GROUP - | Type::TYPE_MESSAGE - | Type::TYPE_BYTES - | Type::TYPE_ENUM => false, - }, - }), + packed: field.field.proto().options.get_or_default().packed(), }) } RuntimeFieldType::Singular(..) => { From 122ee5c87cf81660cf108214469431a476211d57 Mon Sep 17 00:00:00 2001 From: Stepan Koltsov Date: Sun, 25 Feb 2024 21:24:53 +0000 Subject: [PATCH 16/21] Update CHANGELOG.md --- CHANGELOG.md | 1 - 1 file changed, 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b847adea1..d4410cfdb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,6 @@ * [Ignore error of `flush` in `Drop` of `CodedOutputStream`](https://github.com/stepancheg/rust-protobuf/issues/714) * [Faster `encoded_varint64_len`](https://github.com/stepancheg/rust-protobuf/pull/709) * [`reserved` keyword in enums](https://github.com/stepancheg/rust-protobuf/pull/712) -* [repeated primitives are packed by default in proto3](https://github.com/stepancheg/rust-protobuf/pull/707) ## [3.3.0] - 2023-09-30 From 5340b63054cff852db705d28e41076cb7dc5768e Mon Sep 17 00:00:00 2001 From: Martin von Zweigbergk Date: Tue, 4 Oct 2022 21:54:32 -0700 Subject: [PATCH 17/21] add missing newline at end of file to license files --- LICENSE.txt | 2 +- protobuf-codegen/LICENSE.txt | 2 +- protobuf/LICENSE.txt | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/LICENSE.txt b/LICENSE.txt index acce6396f..21f30fa75 100644 --- a/LICENSE.txt +++ b/LICENSE.txt @@ -16,4 +16,4 @@ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE -OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file +OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/protobuf-codegen/LICENSE.txt b/protobuf-codegen/LICENSE.txt index acce6396f..21f30fa75 100644 --- a/protobuf-codegen/LICENSE.txt +++ b/protobuf-codegen/LICENSE.txt @@ -16,4 +16,4 @@ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE -OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file +OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/protobuf/LICENSE.txt b/protobuf/LICENSE.txt index acce6396f..21f30fa75 100644 --- a/protobuf/LICENSE.txt +++ b/protobuf/LICENSE.txt @@ -16,4 +16,4 @@ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE -OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file +OR OTHER DEALINGS IN THE SOFTWARE. From 1ac73f0d0385728ca7249b120d0d13b9be828a18 Mon Sep 17 00:00:00 2001 From: Martin von Zweigbergk Date: Tue, 4 Oct 2022 21:08:25 -0700 Subject: [PATCH 18/21] Add license files to all published crates It seems that this was decided in #394, but then it has just been forgotten in crates added after that PR. --- protobuf-json-mapping/LICENSE.txt | 19 +++++++++++++++++++ protobuf-parse/LICENSE.txt | 19 +++++++++++++++++++ protobuf-support/LICENSE.txt | 19 +++++++++++++++++++ 3 files changed, 57 insertions(+) create mode 100644 protobuf-json-mapping/LICENSE.txt create mode 100644 protobuf-parse/LICENSE.txt create mode 100644 protobuf-support/LICENSE.txt diff --git a/protobuf-json-mapping/LICENSE.txt b/protobuf-json-mapping/LICENSE.txt new file mode 100644 index 000000000..21f30fa75 --- /dev/null +++ b/protobuf-json-mapping/LICENSE.txt @@ -0,0 +1,19 @@ +Copyright (c) 2019 Stepan Koltsov + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE +OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/protobuf-parse/LICENSE.txt b/protobuf-parse/LICENSE.txt new file mode 100644 index 000000000..21f30fa75 --- /dev/null +++ b/protobuf-parse/LICENSE.txt @@ -0,0 +1,19 @@ +Copyright (c) 2019 Stepan Koltsov + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE +OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/protobuf-support/LICENSE.txt b/protobuf-support/LICENSE.txt new file mode 100644 index 000000000..21f30fa75 --- /dev/null +++ b/protobuf-support/LICENSE.txt @@ -0,0 +1,19 @@ +Copyright (c) 2019 Stepan Koltsov + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE +OR OTHER DEALINGS IN THE SOFTWARE. From 56e74cb51f58308bf16cdd08ab733dd9eddf71c5 Mon Sep 17 00:00:00 2001 From: Martin von Zweigbergk Date: Thu, 15 Dec 2022 10:40:59 -0800 Subject: [PATCH 19/21] add Google license to protobuf-parse LICENSE file The license from `protobuf-parse/src/proto/google/protobuf/` should be mentioned in the LICENSE file. --- protobuf-parse/LICENSE.txt | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/protobuf-parse/LICENSE.txt b/protobuf-parse/LICENSE.txt index 21f30fa75..d73be60af 100644 --- a/protobuf-parse/LICENSE.txt +++ b/protobuf-parse/LICENSE.txt @@ -17,3 +17,40 @@ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +----- + +The following applies to src/proto/google/ + +Copyright 2008 Google Inc. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google Inc. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +Code generated by the Protocol Buffer compiler is owned by the owner +of the input file used when generating it. This code is not +standalone and requires a support library to be linked with it. This +support library is itself covered by the above license. From b6d05426eb01eb0973d7efebe0bf54d20eabc830 Mon Sep 17 00:00:00 2001 From: yifei Date: Thu, 28 Jul 2022 16:35:40 +0800 Subject: [PATCH 20/21] fix: set client and server streaming --- protobuf-parse/src/pure/convert/mod.rs | 8 ++++++++ .../src/v2/test_stream_pb.proto | 18 ++++++++++++++++++ 2 files changed, 26 insertions(+) create mode 100644 test-crates/protobuf-codegen-protoc-test/src/v2/test_stream_pb.proto diff --git a/protobuf-parse/src/pure/convert/mod.rs b/protobuf-parse/src/pure/convert/mod.rs index 3bb63f2f2..a18b5e203 100644 --- a/protobuf-parse/src/pure/convert/mod.rs +++ b/protobuf-parse/src/pure/convert/mod.rs @@ -341,6 +341,14 @@ impl<'a> Resolver<'a> { .full_name .to_string(), ); + + if input.client_streaming { + output.set_client_streaming(input.client_streaming); + } + + if input.server_streaming { + output.set_server_streaming(input.server_streaming); + } Ok(output) } diff --git a/test-crates/protobuf-codegen-protoc-test/src/v2/test_stream_pb.proto b/test-crates/protobuf-codegen-protoc-test/src/v2/test_stream_pb.proto new file mode 100644 index 000000000..58737a585 --- /dev/null +++ b/test-crates/protobuf-codegen-protoc-test/src/v2/test_stream_pb.proto @@ -0,0 +1,18 @@ +syntax = "proto2"; + + +message Req { + required int32 a = 1; + repeated string b = 2; +} + +message Resp { + required int32 status = 1; +} + +service TestService { + rpc test_client_streaming(stream Req) returns (Resp); + rpc test_server_streaming(Req) returns (stream Resp); + rpc test_bi_streaming(stream Req) returns (stream Resp); +} + From 16c9dc509267a6673f29563f9a01cc3026cc2144 Mon Sep 17 00:00:00 2001 From: Stepan Koltsov Date: Sun, 25 Feb 2024 21:33:22 +0000 Subject: [PATCH 21/21] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d4410cfdb..335b842ff 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ * [Ignore error of `flush` in `Drop` of `CodedOutputStream`](https://github.com/stepancheg/rust-protobuf/issues/714) * [Faster `encoded_varint64_len`](https://github.com/stepancheg/rust-protobuf/pull/709) * [`reserved` keyword in enums](https://github.com/stepancheg/rust-protobuf/pull/712) +* [Set streaming options in pure parser](https://github.com/stepancheg/rust-protobuf/pull/646) ## [3.3.0] - 2023-09-30