-
Notifications
You must be signed in to change notification settings - Fork 15.5k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
UPB text encoder without using reflection for Rust (used for a messag…
…e's Debug trait) that will print out field number to value entries instead of field name to value entries of a message like how it's expected for the usual text format using reflection. General test for it is done in Rust, and then extensions are tested in UPB as they're not currently supported in Rust-upb. PiperOrigin-RevId: 651113583
- Loading branch information
1 parent
32bcf0b
commit f9dd9ce
Showing
22 changed files
with
1,256 additions
and
466 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
// Protocol Buffers - Google's data interchange format | ||
// Copyright 2024 Google LLC. All rights reserved. | ||
// | ||
// Use of this source code is governed by a BSD-style | ||
// license that can be found in the LICENSE file or at | ||
// https://developers.google.com/open-source/licenses/bsd | ||
|
||
use googletest::prelude::*; | ||
use map_unittest_rust_proto::TestMapWithMessages; | ||
use protobuf_upb::proto; | ||
use unittest_rust_proto::{ | ||
test_all_types::NestedEnum as NestedEnumProto2, | ||
test_all_types::NestedMessage as NestedMessageProto2, TestAllTypes as TestAllTypesProto2, | ||
}; | ||
|
||
#[test] | ||
fn test_debug_string() { | ||
let mut msg = proto!(TestAllTypesProto2 { | ||
optional_int32: 42, | ||
optional_string: "Hello World", | ||
optional_nested_enum: NestedEnumProto2::Bar, | ||
oneof_uint32: 452235, | ||
optional_nested_message: proto!(NestedMessageProto2 { bb: 100 }), | ||
}); | ||
let mut repeated_string = msg.repeated_string_mut(); | ||
repeated_string.push("Hello World"); | ||
repeated_string.push("Hello World"); | ||
repeated_string.push("Hello World"); | ||
|
||
let mut msg_map = TestMapWithMessages::new(); | ||
println!("EMPTY MSG: {:?}", msg_map); // Make sure that we can print an empty message. | ||
msg_map.map_string_all_types_mut().insert("hello", msg.as_view()); | ||
msg_map.map_string_all_types_mut().insert("fizz", msg.as_view()); | ||
msg_map.map_string_all_types_mut().insert("boo", msg.as_view()); | ||
|
||
println!("{:?}", msg_map); | ||
println!("{:?}", msg_map.as_view()); // Make sure that we can print as_view | ||
println!("{:?}", msg_map.as_mut()); // Make sure that we can print as_mut | ||
let golden = r#"12 { | ||
key: "hello" | ||
value { | ||
1: 42 | ||
14: "Hello World" | ||
18 { | ||
1: 100 | ||
} | ||
21: 2 | ||
44: "Hello World" | ||
44: "Hello World" | ||
44: "Hello World" | ||
111: 452235 | ||
} | ||
} | ||
12 { | ||
key: "fizz" | ||
value { | ||
1: 42 | ||
14: "Hello World" | ||
18 { | ||
1: 100 | ||
} | ||
21: 2 | ||
44: "Hello World" | ||
44: "Hello World" | ||
44: "Hello World" | ||
111: 452235 | ||
} | ||
} | ||
12 { | ||
key: "boo" | ||
value { | ||
1: 42 | ||
14: "Hello World" | ||
18 { | ||
1: 100 | ||
} | ||
21: 2 | ||
44: "Hello World" | ||
44: "Hello World" | ||
44: "Hello World" | ||
111: 452235 | ||
} | ||
} | ||
"#; | ||
// C strings are null terminated while Rust strings are not. | ||
let null_terminated_str = format!("{}\0", golden); | ||
assert_that!(format!("{:?}", msg_map), eq(null_terminated_str.as_str())); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
// Protocol Buffers - Google's data interchange format | ||
// Copyright 2024 Google LLC. All rights reserved. | ||
// | ||
// Use of this source code is governed by a BSD-style | ||
// license that can be found in the LICENSE file or at | ||
// https://developers.google.com/open-source/licenses/bsd | ||
|
||
use crate::{upb_MiniTable, RawMessage}; | ||
|
||
extern "C" { | ||
/// Returns the minimum needed length (excluding NULL) that `buf` has to be | ||
/// to hold the `msg`s debug string. | ||
/// | ||
/// SAFETY: | ||
/// - `msg` is pointing at a valid upb_Message with associated minitable | ||
/// `mt` | ||
/// - `buf` is legally writable for `size` bytes (`buf` may be nullptr if | ||
/// `size` is 0) | ||
fn upb_DebugString( | ||
msg: RawMessage, | ||
mt: *const upb_MiniTable, | ||
options: i32, | ||
buf: *mut u8, | ||
size: usize, | ||
) -> usize; | ||
} | ||
|
||
#[allow(dead_code)] | ||
#[repr(i32)] | ||
enum Options { | ||
// When set, prints everything on a single line. | ||
SingleLine = 1, | ||
|
||
// When set, unknown fields are not printed. | ||
SkipUnknown = 2, | ||
|
||
// When set, maps are *not* sorted (this avoids allocating tmp mem). | ||
NoSortMaps = 4, | ||
} | ||
|
||
/// Returns a string of field number to value entries of a message. | ||
/// | ||
/// # Safety | ||
/// - `mt` must correspond to the `msg`s minitable. | ||
pub unsafe fn debug_string(msg: RawMessage, mt: *const upb_MiniTable) -> String { | ||
// Only find out the length first to then allocate a buffer of the minimum size | ||
// needed. | ||
// SAFETY: | ||
// - `msg` is a legally dereferencable upb_Message whose associated minitable is | ||
// `mt` | ||
// - `buf` is nullptr and `buf_len` is 0 | ||
let len = | ||
unsafe { upb_DebugString(msg, mt, Options::NoSortMaps as i32, std::ptr::null_mut(), 0) }; | ||
assert!(len < isize::MAX as usize); | ||
// +1 for the trailing NULL | ||
let mut buf = vec![0u8; len + 1]; | ||
// SAFETY: | ||
// - `msg` is a legally dereferencable upb_Message whose associated minitable is | ||
// `mt` | ||
// - `buf` is legally writable for 'buf_len' bytes | ||
let written_len = unsafe { | ||
upb_DebugString(msg, mt, Options::NoSortMaps as i32, buf.as_mut_ptr(), buf.len()) | ||
}; | ||
assert_eq!(len, written_len); | ||
String::from_utf8_lossy(buf.as_slice()).to_string() | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.