├── protobuf-fuzz ├── src │ ├── .gitignore │ └── all_types_pb.proto ├── fuzz │ ├── .gitignore │ ├── fuzz_targets │ │ ├── all.rs │ │ ├── map.rs │ │ ├── map_read.rs │ │ ├── repeated.rs │ │ ├── singular.rs │ │ ├── empty_message.rs │ │ ├── repeated_read.rs │ │ ├── singular_read.rs │ │ └── empty_message_read.rs │ └── Cargo.toml ├── build.rs └── Cargo.toml ├── perftest ├── bytes │ ├── src │ │ ├── .gitignore │ │ ├── lib.rs │ │ └── messages.proto │ ├── Cargo.toml │ └── build.rs └── vs-cxx │ ├── .gitignore │ ├── build-perftest.sh │ ├── build-perftest-data.sh │ ├── build-perftest-cxx.sh │ ├── build.rs │ ├── Cargo.toml │ └── perftest_data.proto ├── protoc ├── test-protoc │ ├── src │ │ ├── .gitignore │ │ ├── data.proto │ │ └── lib.rs │ ├── Cargo.toml │ └── build.rs ├── test.sh ├── Cargo.toml ├── README.md └── LICENSE.txt ├── protobuf-test ├── src │ ├── google │ │ ├── mod.rs │ │ └── protobuf │ │ │ ├── .gitignore │ │ │ ├── README.md │ │ │ ├── import-tests.sh │ │ │ ├── unittest_no_arena_import.proto │ │ │ ├── unittest_import_public.proto │ │ │ ├── unittest_empty.proto │ │ │ ├── unittest_import_public_lite.proto │ │ │ ├── unittest_lite_imports_nonlite.proto │ │ │ ├── unittest_arena.proto │ │ │ ├── unittest_no_arena_lite.proto │ │ │ ├── unittest_preserve_unknown_enum2.proto │ │ │ ├── unittest_no_generic_services.proto │ │ │ ├── unittest_import_lite.proto │ │ │ ├── unittest_drop_unknown_fields.proto │ │ │ ├── unittest_mset_wire_format.proto │ │ │ └── unittest_embed_optimize_for.proto │ ├── common │ │ ├── v2 │ │ │ ├── .gitignore │ │ │ ├── test_root.rs │ │ │ ├── test_import_descriptor.rs │ │ │ ├── test_oneof_recursive.rs │ │ │ ├── test_nonunique_enum.rs │ │ │ ├── test_oneof_expose.rs │ │ │ ├── test_nonunique_enum_pb.proto │ │ │ ├── test_well_known_types.rs │ │ │ ├── test_import_descriptor_pb.proto │ │ │ ├── test_oneof_recursive_pb.proto │ │ │ ├── test_default.rs │ │ │ ├── test_sync_pb.proto │ │ │ ├── test_default_pb.proto │ │ │ ├── test_enum_values_pb.proto │ │ │ ├── test_root_pb.proto │ │ │ ├── test_oneof_expose_pb.proto │ │ │ ├── test_singular_concat_pb.proto │ │ │ ├── test_ident.rs │ │ │ ├── test_lite_runtime.rs │ │ │ ├── test_enable_lite_runtime.rs │ │ │ ├── test_generate_accessors.rs │ │ │ ├── test_lite_runtime_pb.proto │ │ │ ├── test_map_carllerche_pb.proto │ │ │ ├── test_enum_alias_pb.proto │ │ │ ├── test_enable_lite_runtime_pb.proto │ │ │ ├── test_repeated_packed_pb.proto │ │ │ ├── test_enum_values.rs │ │ │ ├── test_map_simple_pb.proto │ │ │ ├── test_carllerche_bytes_pb.proto │ │ │ ├── test_singular_field_option.rs │ │ │ ├── test_repeated_field_vec.rs │ │ │ ├── test_singular_concat.rs │ │ │ ├── test_enum_unknown_values_preserved.rs │ │ │ ├── test_enum_unknown_values_preserved_pb.proto │ │ │ ├── test_carllerche_bytes.rs │ │ │ ├── test_repeated_field_vec_pb.proto │ │ │ ├── test_generate_accessors_pb.proto │ │ │ ├── test_enum_alias.rs │ │ │ ├── test_well_known_types_pb.proto │ │ │ ├── test_serde_derive_pb.proto │ │ │ ├── test_oneof_pb.proto │ │ │ ├── test_singular_field_option_pb.proto │ │ │ ├── test_sync.rs │ │ │ ├── test_map_carllerche.rs │ │ │ ├── test_ident_pb.proto │ │ │ ├── test_ext.rs │ │ │ ├── test_fmt_json_well_known_pb.proto │ │ │ ├── test_ext_pb.proto │ │ │ ├── test_fmt_text_format_0_pb.proto │ │ │ ├── test_oneof.rs │ │ │ └── test_map_simple.rs │ │ ├── v3 │ │ │ └── .gitignore │ │ └── mod.rs │ ├── v2 │ │ ├── .gitignore │ │ ├── test-sanitize-file-name_pb.proto │ │ ├── test_unknown_suffix_pb.proto3 │ │ ├── test_import_nonunique_1_pb.proto │ │ ├── test_import_nonunique_2_pb.proto │ │ ├── test_oneof_group.rs │ │ ├── test_import_root_imported_pb.proto │ │ ├── test_unknown_suffix.rs │ │ ├── struct.proto │ │ ├── test_special~characters file{name}_pb.proto │ │ ├── test_oneof_group_pb.proto │ │ ├── test_import_nested_imported_pb.proto │ │ ├── test_required_pb.proto │ │ ├── test_import_pkg_nested_imported_pb.proto │ │ ├── test_import_root_pb.proto │ │ ├── test_group_pb.proto │ │ ├── test_import_nested_pb.proto │ │ ├── test_import_nonunique_pb.proto │ │ ├── test_oneof_default_value.rs │ │ ├── test_import_pkg_nested_pb.proto │ │ ├── test_carllerche_bytes_default_value_pb.proto │ │ ├── test_carllerche_bytes_default_value.rs │ │ ├── test_required.rs │ │ ├── test_oneof_default_value_pb.proto │ │ ├── test_default_values.rs │ │ └── test_default_values_pb.proto │ ├── v3 │ │ ├── .gitignore │ │ ├── test_issue_190_pb.proto │ │ ├── test_ident_pb.proto │ │ ├── test_zeros_are_not_written.rs │ │ └── test_zeros_are_not_written_pb.proto │ ├── interop │ │ └── mod.rs │ └── lib.rs ├── .gitignore ├── test.sh ├── Cargo.toml └── README.md ├── interop └── cxx │ ├── .gitignore │ ├── compile.sh │ └── interop.cc ├── protobuf-codegen-pure-test ├── src │ ├── interop │ │ └── .gitignore │ ├── common │ │ ├── mod.rs │ │ ├── v2 │ │ │ └── .gitignore │ │ └── v3 │ │ │ └── .gitignore │ ├── v2 │ │ └── .gitignore │ ├── v3 │ │ └── .gitignore │ ├── google │ │ └── protobuf │ │ │ └── .gitignore │ └── lib.rs ├── .gitignore ├── test.sh └── Cargo.toml ├── protobuf ├── src │ ├── oneof.rs │ ├── text_format │ │ ├── lexer │ │ │ ├── num_lit.rs │ │ │ ├── json_number_lit.rs │ │ │ ├── parser_language.rs │ │ │ ├── int.rs │ │ │ ├── loc.rs │ │ │ ├── mod.rs │ │ │ ├── str_lit.rs │ │ │ ├── token.rs │ │ │ └── float.rs │ │ └── mod.rs │ ├── json │ │ ├── float.rs │ │ ├── json_name.rs │ │ └── mod.rs │ ├── reflect │ │ ├── reflect_deep_eq.rs │ │ ├── accessor │ │ │ └── mod.rs │ │ ├── runtime_type_box.rs │ │ ├── rt.rs │ │ ├── type_dynamic.rs │ │ ├── mod.rs │ │ ├── find_message_or_enum.rs │ │ ├── transmute_eq.rs │ │ └── runtime_type_dynamic.rs │ ├── clear.rs │ ├── well_known_types │ │ └── mod.rs │ ├── paginate.rs │ ├── misc.rs │ ├── cached_size.rs │ ├── ext.rs │ ├── buf_read_or_reader.rs │ ├── zigzag.rs │ ├── varint.rs │ ├── lib.rs │ └── chars.rs ├── README.md ├── Cargo.toml ├── LICENSE.txt ├── benches │ └── coded_output_stream.rs ├── regenerate.sh └── build.rs ├── .gitmodules ├── .editorconfig ├── protobuf-codegen ├── src │ ├── bin │ │ ├── protoc-gen-rust.rs │ │ └── protobuf-bin-gen-rust-do-not-use.rs │ ├── file_and_mod.rs │ ├── inside.rs │ ├── syntax.rs │ ├── file_descriptor.rs │ ├── serde.rs │ ├── amend_io_error_util.rs │ ├── compiler_plugin.rs │ ├── strx.rs │ ├── map.rs │ ├── case_convert.rs │ ├── well_known_types.rs │ └── file.rs ├── Cargo.toml ├── LICENSE.txt └── README.md ├── .gitignore ├── ci ├── env-debug.sh ├── run.sh └── install-protobuf.sh ├── Cargo.toml ├── protobuf-codegen-pure ├── src │ ├── bin │ │ └── parse-and-typecheck.rs │ └── test_against_protobuf_protos.rs ├── Cargo.toml ├── LICENSE.txt └── README.md ├── protobuf-test-common ├── src │ ├── lib.rs │ ├── json_tests.rs │ ├── serialize_deserialize_tests.rs │ └── hex.rs └── Cargo.toml ├── proto └── google │ └── protobuf │ ├── fetch-protos.sh │ ├── source_context.proto │ └── empty.proto ├── protoc-rust ├── Cargo.toml ├── LICENSE.txt └── README.md ├── .travis.yml ├── LICENSE.txt ├── CONTRIBUTING.md └── FAQ.md /protobuf-fuzz/src/.gitignore: -------------------------------------------------------------------------------- 1 | *_pb.rs 2 | -------------------------------------------------------------------------------- /perftest/bytes/src/.gitignore: -------------------------------------------------------------------------------- 1 | messages.rs 2 | -------------------------------------------------------------------------------- /protoc/test-protoc/src/.gitignore: -------------------------------------------------------------------------------- 1 | data.rs 2 | -------------------------------------------------------------------------------- /protobuf-test/src/google/mod.rs: -------------------------------------------------------------------------------- 1 | mod protobuf; 2 | -------------------------------------------------------------------------------- /interop/cxx/.gitignore: -------------------------------------------------------------------------------- 1 | interop 2 | interop_pb.pb.* 3 | -------------------------------------------------------------------------------- /protobuf-codegen-pure-test/src/interop/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | -------------------------------------------------------------------------------- /protobuf-test/.gitignore: -------------------------------------------------------------------------------- 1 | *_pb.rs 2 | *_pb_proto3.rs 3 | -------------------------------------------------------------------------------- /protobuf-test/src/common/v2/.gitignore: -------------------------------------------------------------------------------- 1 | mod.rs 2 | *_pb.rs 3 | -------------------------------------------------------------------------------- /protobuf-test/src/common/v3/.gitignore: -------------------------------------------------------------------------------- 1 | *.rs 2 | *.proto 3 | -------------------------------------------------------------------------------- /protobuf-codegen-pure-test/.gitignore: -------------------------------------------------------------------------------- 1 | *_pb.rs 2 | *_pb_proto3.rs 3 | -------------------------------------------------------------------------------- /protobuf-codegen-pure-test/src/common/mod.rs: -------------------------------------------------------------------------------- 1 | mod v2; 2 | 3 | mod v3; 4 | -------------------------------------------------------------------------------- /protobuf-fuzz/fuzz/.gitignore: -------------------------------------------------------------------------------- 1 | 2 | target 3 | corpus 4 | artifacts 5 | -------------------------------------------------------------------------------- /protobuf-test/src/google/protobuf/.gitignore: -------------------------------------------------------------------------------- 1 | unittest*.rs 2 | mod.rs 3 | -------------------------------------------------------------------------------- /protobuf-test/src/v2/.gitignore: -------------------------------------------------------------------------------- 1 | mod.rs 2 | *_pb.rs 3 | *_pb_proto3.rs 4 | -------------------------------------------------------------------------------- /protobuf-test/src/v3/.gitignore: -------------------------------------------------------------------------------- 1 | mod.rs 2 | *_pb.rs 3 | *_pb_proto3.rs 4 | -------------------------------------------------------------------------------- /protoc/test-protoc/src/data.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto2"; 2 | 3 | message FooBar { 4 | } 5 | -------------------------------------------------------------------------------- /protobuf-codegen-pure-test/src/v2/.gitignore: -------------------------------------------------------------------------------- 1 | # All files in this directory are generated 2 | * 3 | -------------------------------------------------------------------------------- /protobuf-codegen-pure-test/src/v3/.gitignore: -------------------------------------------------------------------------------- 1 | # All files in this directory are generated 2 | * 3 | -------------------------------------------------------------------------------- /protobuf-test/src/v2/test-sanitize-file-name_pb.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto2"; 2 | 3 | message FooBar {} 4 | -------------------------------------------------------------------------------- /protobuf-codegen-pure-test/src/common/v2/.gitignore: -------------------------------------------------------------------------------- 1 | # All files in this directory are generated 2 | * 3 | -------------------------------------------------------------------------------- /protobuf-codegen-pure-test/src/common/v3/.gitignore: -------------------------------------------------------------------------------- 1 | # All files in this directory are generated 2 | * 3 | -------------------------------------------------------------------------------- /protobuf/src/oneof.rs: -------------------------------------------------------------------------------- 1 | /// Trait implemented by all oneof types in generated code. 2 | pub trait Oneof {} 3 | -------------------------------------------------------------------------------- /protoc/test-protoc/src/lib.rs: -------------------------------------------------------------------------------- 1 | extern crate protobuf; 2 | 3 | mod data; 4 | 5 | pub use data::FooBar; 6 | -------------------------------------------------------------------------------- /protobuf-codegen-pure-test/src/google/protobuf/.gitignore: -------------------------------------------------------------------------------- 1 | # All files in this directory are generated 2 | * 3 | -------------------------------------------------------------------------------- /protobuf-test/src/v2/test_unknown_suffix_pb.proto3: -------------------------------------------------------------------------------- 1 | syntax = "proto2"; 2 | 3 | message TestUnknownSuffix {} 4 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "google-protobuf"] 2 | path = google-protobuf 3 | url = https://github.com/google/protobuf 4 | -------------------------------------------------------------------------------- /protobuf/src/text_format/lexer/num_lit.rs: -------------------------------------------------------------------------------- 1 | #[derive(Copy, Clone)] 2 | pub enum NumLit { 3 | U64(u64), 4 | F64(f64), 5 | } 6 | -------------------------------------------------------------------------------- /protobuf-test/src/v2/test_import_nonunique_1_pb.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto2"; 2 | 3 | package nonunique_1; 4 | 5 | message Nonunique {} 6 | -------------------------------------------------------------------------------- /protobuf-test/src/v2/test_import_nonunique_2_pb.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto2"; 2 | 3 | package nonunique_2; 4 | 5 | message Nonunique {} 6 | -------------------------------------------------------------------------------- /protobuf-test/src/v2/test_oneof_group.rs: -------------------------------------------------------------------------------- 1 | use super::test_oneof_group_pb::A; 2 | 3 | #[test] 4 | fn test() { 5 | A::new(); 6 | } 7 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | [*] 2 | end_of_line = lf 3 | insert_final_newline = true 4 | charset = utf-8 5 | indent_style = space 6 | indent_size = 4 7 | -------------------------------------------------------------------------------- /protobuf-test/src/common/v2/test_root.rs: -------------------------------------------------------------------------------- 1 | use super::test_root_pb::*; 2 | 3 | #[test] 4 | fn test() { 5 | let _ = Root::new(); 6 | } 7 | -------------------------------------------------------------------------------- /perftest/bytes/src/lib.rs: -------------------------------------------------------------------------------- 1 | #![cfg(feature = "bytes")] 2 | 3 | extern crate protobuf; 4 | 5 | extern crate bytes; 6 | 7 | pub mod messages; 8 | -------------------------------------------------------------------------------- /perftest/vs-cxx/.gitignore: -------------------------------------------------------------------------------- 1 | perftest 2 | perftest-cxx 3 | perftest_proto.rs 4 | perftest_data.pbbin 5 | perftest_data.pb.* 6 | perftest_data.rs 7 | -------------------------------------------------------------------------------- /protobuf-codegen/src/bin/protoc-gen-rust.rs: -------------------------------------------------------------------------------- 1 | extern crate protobuf_codegen; 2 | 3 | fn main() { 4 | protobuf_codegen::protoc_gen_rust_main(); 5 | } 6 | -------------------------------------------------------------------------------- /protobuf-test/test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh -ex 2 | 3 | cd $(dirname $0) 4 | 5 | cargo test --features="$RUST_PROTOBUF_FEATURES" 6 | 7 | # vim: set ts=4 sw=4 et: 8 | -------------------------------------------------------------------------------- /protobuf-test/src/common/v2/test_import_descriptor.rs: -------------------------------------------------------------------------------- 1 | use super::test_import_descriptor_pb::*; 2 | 3 | #[test] 4 | fn test() { 5 | let _ = FooBar::new(); 6 | } 7 | -------------------------------------------------------------------------------- /protobuf-test/src/common/v2/test_oneof_recursive.rs: -------------------------------------------------------------------------------- 1 | use super::test_oneof_recursive_pb::*; 2 | 3 | #[test] 4 | fn test() { 5 | let _ = LinkedList::new(); 6 | } 7 | -------------------------------------------------------------------------------- /protobuf-codegen-pure-test/test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh -ex 2 | 3 | cd $(dirname $0) 4 | 5 | cargo test --features="$RUST_PROTOBUF_FEATURES" 6 | 7 | # vim: set ts=4 sw=4 et: 8 | -------------------------------------------------------------------------------- /protobuf-test/src/common/v2/test_nonunique_enum.rs: -------------------------------------------------------------------------------- 1 | use super::test_nonunique_enum_pb::*; 2 | 3 | #[test] 4 | fn test() { 5 | let _ = message_a::EnumA::FOO; 6 | } 7 | -------------------------------------------------------------------------------- /protobuf-test/src/google/protobuf/README.md: -------------------------------------------------------------------------------- 1 | Files copied from 2 | [Google protobuf implementation](https://github.com/google/protobuf/tree/master/src/google/protobuf) 3 | -------------------------------------------------------------------------------- /protobuf-test/src/common/mod.rs: -------------------------------------------------------------------------------- 1 | // v2 tests which must be compatible with v3 tests 2 | mod v2; 3 | 4 | // v3 tests are generated from v2 tests by copy&replace 5 | mod v3; 6 | -------------------------------------------------------------------------------- /protobuf-test/src/interop/mod.rs: -------------------------------------------------------------------------------- 1 | // Disable on Windows because it's hard to compile interop tools on travis 2 | #![cfg(not(windows))] 3 | 4 | mod interop_pb; 5 | mod json; 6 | -------------------------------------------------------------------------------- /protobuf-test/src/v2/test_import_root_imported_pb.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto2"; 2 | 3 | message ImportedMessage { 4 | } 5 | 6 | enum ImportedEnum { 7 | SOMETHING = 1; 8 | } 9 | -------------------------------------------------------------------------------- /protobuf-test/src/common/v2/test_oneof_expose.rs: -------------------------------------------------------------------------------- 1 | use super::test_oneof_expose_pb::*; 2 | 3 | #[test] 4 | fn test_simple() { 5 | let _aaa = TestOneofExpose::new().aaa; 6 | } 7 | -------------------------------------------------------------------------------- /protobuf-test/src/v2/test_unknown_suffix.rs: -------------------------------------------------------------------------------- 1 | use super::test_unknown_suffix_pb_proto3::TestUnknownSuffix; 2 | 3 | #[test] 4 | fn test() { 5 | TestUnknownSuffix::new(); 6 | } 7 | -------------------------------------------------------------------------------- /protobuf/src/json/float.rs: -------------------------------------------------------------------------------- 1 | pub const PROTOBUF_JSON_NAN: &str = "NaN"; 2 | pub const PROTOBUF_JSON_INF: &str = "Infinity"; 3 | pub const PROTOBUF_JSON_MINUS_INF: &str = "-Infinity"; 4 | -------------------------------------------------------------------------------- /protobuf-test/src/v2/struct.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto2"; 2 | 3 | // this file just checks that file name is properly escaped, 4 | // because `struct` is a keyword in rust 5 | message KeepTheFile {} 6 | -------------------------------------------------------------------------------- /protobuf-test/src/common/v2/test_nonunique_enum_pb.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto2"; 2 | 3 | message MessageA { 4 | enum EnumA { FOO = 0; } 5 | } 6 | message MessageB { 7 | enum EnumB { FOO = 0; } 8 | } 9 | -------------------------------------------------------------------------------- /protobuf-test/src/common/v2/test_well_known_types.rs: -------------------------------------------------------------------------------- 1 | use super::test_well_known_types_pb::*; 2 | 3 | #[test] 4 | fn test() { 5 | // Just check it typechecks 6 | UsesWellKnownTypes::new(); 7 | } 8 | -------------------------------------------------------------------------------- /protobuf/README.md: -------------------------------------------------------------------------------- 1 | ## How to develop rust-protobuf itself 2 | 3 | `cargo test --all` to build everything. 4 | 5 | If code generator is changed, code needs to be regenerated, see 6 | `regenerate.sh`. 7 | -------------------------------------------------------------------------------- /perftest/vs-cxx/build-perftest.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh -ex 2 | 3 | cd $(dirname $0) 4 | 5 | ./build-perftest-data.sh 6 | cargo build --release 7 | ./build-perftest-cxx.sh 8 | 9 | # vim: set ts=4 sw=4 et: 10 | -------------------------------------------------------------------------------- /protobuf-test/src/v2/test_special~characters file{name}_pb.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto2"; 2 | 3 | // More test that filenames are sanitized, even imports. 4 | 5 | package special; 6 | 7 | message Outer { 8 | } 9 | -------------------------------------------------------------------------------- /perftest/vs-cxx/build-perftest-data.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh -ex 2 | 3 | cd $(dirname $0) 4 | protoc ./perftest_data.proto --encode=PerftestData < perftest_data.pbtxt > perftest_data.pbbin 5 | 6 | # vim: set ts=4 sw=4 et: 7 | -------------------------------------------------------------------------------- /protobuf-fuzz/fuzz/fuzz_targets/all.rs: -------------------------------------------------------------------------------- 1 | #![no_main] 2 | #[macro_use] extern crate libfuzzer_sys; 3 | extern crate protobuf_fuzz; 4 | 5 | fuzz_target!(|data: &[u8]| { 6 | protobuf_fuzz::fuzz_target_all(data) 7 | }); 8 | -------------------------------------------------------------------------------- /protobuf-fuzz/fuzz/fuzz_targets/map.rs: -------------------------------------------------------------------------------- 1 | #![no_main] 2 | #[macro_use] extern crate libfuzzer_sys; 3 | extern crate protobuf_fuzz; 4 | 5 | fuzz_target!(|data: &[u8]| { 6 | protobuf_fuzz::fuzz_target_map(data) 7 | }); 8 | -------------------------------------------------------------------------------- /protobuf-test/src/common/v2/test_import_descriptor_pb.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto2"; 2 | 3 | import "google/protobuf/descriptor.proto"; 4 | 5 | message FooBar { 6 | optional .google.protobuf.DescriptorProto d = 1; 7 | } 8 | -------------------------------------------------------------------------------- /protobuf-fuzz/fuzz/fuzz_targets/map_read.rs: -------------------------------------------------------------------------------- 1 | #![no_main] 2 | #[macro_use] extern crate libfuzzer_sys; 3 | extern crate protobuf_fuzz; 4 | 5 | fuzz_target!(|data: &[u8]| { 6 | protobuf_fuzz::fuzz_target_map_read(data) 7 | }); 8 | -------------------------------------------------------------------------------- /protobuf-fuzz/fuzz/fuzz_targets/repeated.rs: -------------------------------------------------------------------------------- 1 | #![no_main] 2 | #[macro_use] extern crate libfuzzer_sys; 3 | extern crate protobuf_fuzz; 4 | 5 | fuzz_target!(|data: &[u8]| { 6 | protobuf_fuzz::fuzz_target_repeated(data) 7 | }); 8 | -------------------------------------------------------------------------------- /protobuf-fuzz/fuzz/fuzz_targets/singular.rs: -------------------------------------------------------------------------------- 1 | #![no_main] 2 | #[macro_use] extern crate libfuzzer_sys; 3 | extern crate protobuf_fuzz; 4 | 5 | fuzz_target!(|data: &[u8]| { 6 | protobuf_fuzz::fuzz_target_singular(data) 7 | }); 8 | -------------------------------------------------------------------------------- /protobuf-test/src/v2/test_oneof_group_pb.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto2"; 2 | 3 | package test_oneof_group; 4 | 5 | message A { 6 | oneof b { 7 | group C = 1 { 8 | optional int32 d = 2; 9 | } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /perftest/vs-cxx/build-perftest-cxx.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh -ex 2 | 3 | protoc --cpp_out=. ./perftest_data.proto 4 | clang++ -std=c++11 -O3 -g -Wall -o perftest-cxx perftest-cxx.cxx perftest_data.pb.cc -lprotobuf 5 | 6 | # vim: set ts=4 sw=4 et: 7 | -------------------------------------------------------------------------------- /perftest/vs-cxx/build.rs: -------------------------------------------------------------------------------- 1 | extern crate protoc_rust; 2 | 3 | fn main() { 4 | protoc_rust::Args::new() 5 | .out_dir(".") 6 | .input("perftest_data.proto") 7 | .run() 8 | .expect("protoc"); 9 | } 10 | -------------------------------------------------------------------------------- /protobuf-fuzz/fuzz/fuzz_targets/empty_message.rs: -------------------------------------------------------------------------------- 1 | #![no_main] 2 | #[macro_use] extern crate libfuzzer_sys; 3 | extern crate protobuf_fuzz; 4 | 5 | fuzz_target!(|data: &[u8]| { 6 | protobuf_fuzz::fuzz_target_empty_message(data) 7 | }); 8 | -------------------------------------------------------------------------------- /protobuf-fuzz/fuzz/fuzz_targets/repeated_read.rs: -------------------------------------------------------------------------------- 1 | #![no_main] 2 | #[macro_use] extern crate libfuzzer_sys; 3 | extern crate protobuf_fuzz; 4 | 5 | fuzz_target!(|data: &[u8]| { 6 | protobuf_fuzz::fuzz_target_repeated_read(data) 7 | }); 8 | -------------------------------------------------------------------------------- /protobuf-fuzz/fuzz/fuzz_targets/singular_read.rs: -------------------------------------------------------------------------------- 1 | #![no_main] 2 | #[macro_use] extern crate libfuzzer_sys; 3 | extern crate protobuf_fuzz; 4 | 5 | fuzz_target!(|data: &[u8]| { 6 | protobuf_fuzz::fuzz_target_singular_read(data) 7 | }); 8 | -------------------------------------------------------------------------------- /protobuf-test/src/common/v2/test_oneof_recursive_pb.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto2"; 2 | 3 | package test_oneof_recursive; 4 | 5 | message LinkedList { 6 | oneof x { 7 | bool tail = 1; 8 | LinkedList node = 2; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /protobuf-test/src/v2/test_import_nested_imported_pb.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto2"; 2 | 3 | message ContainerForNested { 4 | message NestedMessage { 5 | } 6 | 7 | enum NestedEnum { 8 | RED = 1; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /protobuf-test/src/common/v2/test_default.rs: -------------------------------------------------------------------------------- 1 | use super::test_default_pb::*; 2 | 3 | #[test] 4 | fn test_default_for_amp_message() { 5 | let none: Option<&TestDefault> = None; 6 | assert_eq!(0, none.unwrap_or_default().get_i()); 7 | } 8 | -------------------------------------------------------------------------------- /protobuf-test/src/common/v2/test_sync_pb.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto2"; 2 | 3 | import "rustproto.proto"; 4 | option (rustproto.generate_accessors_all) = true; 5 | 6 | message TestSync { 7 | optional int32 int32_field = 3; 8 | } 9 | 10 | -------------------------------------------------------------------------------- /protobuf-fuzz/fuzz/fuzz_targets/empty_message_read.rs: -------------------------------------------------------------------------------- 1 | #![no_main] 2 | #[macro_use] extern crate libfuzzer_sys; 3 | extern crate protobuf_fuzz; 4 | 5 | fuzz_target!(|data: &[u8]| { 6 | protobuf_fuzz::fuzz_target_empty_message_read(data) 7 | }); 8 | -------------------------------------------------------------------------------- /protobuf-test/src/v2/test_required_pb.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto2"; 2 | 3 | package test_required; 4 | 5 | message TestRequired { 6 | required bool b = 5; 7 | } 8 | 9 | message TestRequiredOuter { 10 | required TestRequired inner = 1; 11 | } 12 | -------------------------------------------------------------------------------- /protobuf-codegen/src/file_and_mod.rs: -------------------------------------------------------------------------------- 1 | use crate::customize::Customize; 2 | use crate::rust_name::RustRelativePath; 3 | 4 | pub(crate) struct FileAndMod { 5 | pub file: String, 6 | pub relative_mod: RustRelativePath, 7 | pub customize: Customize, 8 | } 9 | -------------------------------------------------------------------------------- /protobuf-test/src/common/v2/test_default_pb.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto2"; 2 | 3 | import "rustproto.proto"; 4 | option (rustproto.generate_accessors_all) = true; 5 | 6 | package test_default; 7 | 8 | message TestDefault { 9 | optional int32 i = 1; 10 | } 11 | -------------------------------------------------------------------------------- /protobuf-test/src/common/v2/test_enum_values_pb.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto2"; 2 | 3 | package test_enum_values; 4 | 5 | enum TestEnumValuesEnum { 6 | UNKNOWN = 0; 7 | WINTER = 11; 8 | SPRING = 22; 9 | SUMMER = 33; 10 | AUTUMN = 44; 11 | } 12 | -------------------------------------------------------------------------------- /protobuf-test/src/v2/test_import_pkg_nested_imported_pb.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto2"; 2 | 3 | package foo.baz; 4 | 5 | message ContainerForNested { 6 | message NestedMessage { 7 | } 8 | 9 | enum NestedEnum { 10 | RED = 1; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /protobuf-test/src/v2/test_import_root_pb.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto2"; 2 | 3 | import "test_import_root_imported_pb.proto"; 4 | 5 | message ContainsImported { 6 | optional ImportedMessage imported_message = 1; 7 | optional ImportedEnum imported_enum = 2; 8 | } 9 | -------------------------------------------------------------------------------- /protobuf-test/src/v2/test_group_pb.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto2"; 2 | 3 | message MessageWithGroup { 4 | optional string aaa = 1; 5 | 6 | repeated group Identifier = 18 { 7 | optional int32 iii = 19; 8 | optional string sss = 20; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.dSYM 2 | *~ 3 | .*.swp 4 | .gdb_history 5 | tmp* 6 | *.dylib 7 | *.rlib 8 | *.bin 9 | *.so 10 | src/test/v*/pb_*.rs 11 | src/test/v*/*_pb.rs 12 | src/test/lib 13 | protobuf-bin-gen-rust 14 | protoc-gen-rust 15 | target/ 16 | Cargo.lock 17 | .idea 18 | *.iml 19 | -------------------------------------------------------------------------------- /protobuf-test/src/common/v2/test_root_pb.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto2"; 2 | 3 | // no namespace declaration 4 | 5 | message Root { 6 | message Nested { 7 | } 8 | 9 | // accessing nested message in root namespace 10 | repeated .Root.Nested nested = 1; 11 | } 12 | -------------------------------------------------------------------------------- /protobuf-test/src/v2/test_import_nested_pb.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto2"; 2 | 3 | import "test_import_nested_imported_pb.proto"; 4 | 5 | message ContainsImportedNested { 6 | optional ContainerForNested.NestedMessage m = 1; 7 | optional ContainerForNested.NestedEnum e = 2; 8 | } 9 | -------------------------------------------------------------------------------- /protobuf-test/src/common/v2/test_oneof_expose_pb.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto2"; 2 | 3 | import "rustproto.proto"; 4 | 5 | option (rustproto.expose_oneof_all) = true; 6 | 7 | message TestOneofExpose { 8 | oneof aaa { 9 | string s = 1; 10 | int32 x = 2; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /protobuf-test/src/v2/test_import_nonunique_pb.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto2"; 2 | 3 | import "test_import_nonunique_1_pb.proto"; 4 | import "test_import_nonunique_2_pb.proto"; 5 | 6 | message TestImportNonunque { 7 | optional nonunique_1.Nonunique n1 = 1; 8 | optional nonunique_2.Nonunique n2 = 2; 9 | } 10 | -------------------------------------------------------------------------------- /protobuf-test/src/common/v2/test_singular_concat_pb.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto2"; 2 | 3 | import "rustproto.proto"; 4 | option (rustproto.generate_accessors_all) = true; 5 | 6 | 7 | package test_singular_concar; 8 | 9 | message TestSingularConcat { 10 | optional string s = 1; 11 | optional bytes b = 2; 12 | } 13 | -------------------------------------------------------------------------------- /protobuf-test/src/v2/test_oneof_default_value.rs: -------------------------------------------------------------------------------- 1 | use super::test_oneof_default_value_pb::*; 2 | 3 | #[test] 4 | fn test() { 5 | let m = TestOneofDefaultValue::new(); 6 | assert_eq!(9.0, m.get_double_field()); 7 | assert_eq!("ss", m.get_string_field()); 8 | assert_eq!(b"bb", m.get_bytes_field()); 9 | } 10 | -------------------------------------------------------------------------------- /protobuf-test/src/v3/test_issue_190_pb.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package issue_190; 4 | 5 | message A { 6 | enum Type { 7 | STRING = 0; 8 | } 9 | } 10 | 11 | message B { 12 | message C { 13 | oneof something { 14 | A.Type type = 1; 15 | } 16 | } 17 | repeated C somethings = 1; 18 | } 19 | -------------------------------------------------------------------------------- /protobuf/src/text_format/lexer/json_number_lit.rs: -------------------------------------------------------------------------------- 1 | use std::fmt; 2 | 3 | #[derive(Clone, Debug, Eq, PartialEq)] 4 | pub struct JsonNumberLit(pub(crate) String); 5 | 6 | impl fmt::Display for JsonNumberLit { 7 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 8 | fmt::Display::fmt(&self.0, f) 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /protobuf/src/text_format/lexer/parser_language.rs: -------------------------------------------------------------------------------- 1 | /// We use the same lexer/tokenizer for all parsers for simplicity 2 | #[derive(Copy, Clone, Debug, Eq, PartialEq)] 3 | pub enum ParserLanguage { 4 | // `.proto` files 5 | Proto, 6 | // Protobuf text format 7 | TextFormat, 8 | // JSON 9 | Json, 10 | } 11 | -------------------------------------------------------------------------------- /protobuf-test/src/v2/test_import_pkg_nested_pb.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto2"; 2 | 3 | import "test_import_pkg_nested_imported_pb.proto"; 4 | 5 | package foo.bar; 6 | 7 | message ContainsImportedNested { 8 | optional foo.baz.ContainerForNested.NestedMessage m = 1; 9 | optional foo.baz.ContainerForNested.NestedEnum e = 2; 10 | } 11 | -------------------------------------------------------------------------------- /interop/cxx/compile.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -ex 4 | 5 | cd $(dirname $0) 6 | 7 | protoc --cpp_out=. interop_pb.proto 8 | c++ --version 9 | c++ -std=c++11 -Wall -O1 \ 10 | interop.cc interop_pb.pb.cc \ 11 | `pkg-config --cflags --libs protobuf` \ 12 | -o interop 13 | ./interop self-test 14 | 15 | # vim: set ts=4 sw=4 et: 16 | -------------------------------------------------------------------------------- /protobuf/src/reflect/reflect_deep_eq.rs: -------------------------------------------------------------------------------- 1 | /// Special version of eq, which 2 | /// * considers `NaN` values equal 3 | /// * panics if parameters have different types at runtime 4 | /// (e. g. `ReflectRepeated` of `u32` and `u64` must not be compared. 5 | pub(crate) trait ReflectDeepEq { 6 | fn reflect_deep_eq(&self, that: &Self) -> bool; 7 | } 8 | -------------------------------------------------------------------------------- /protoc/test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh -e 2 | 3 | cd $(dirname $0) 4 | 5 | ( 6 | echo "building protoc-gen-rust" 7 | cd ../protobuf-codegen 8 | cargo build --bin=protoc-gen-rust 9 | ) 10 | 11 | echo "cargo check in test-protoc" 12 | cd test-protoc 13 | exec cargo check --features=$RUST_PROTOBUF_FEATURES 14 | 15 | # vim: set ts=4 sw=4 et: 16 | -------------------------------------------------------------------------------- /ci/env-debug.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # Print environment in travis job 4 | # The script is cheap but may save hours of debugging 5 | 6 | set -e 7 | 8 | echo "pwd: `pwd`" 9 | echo "uname: `uname`" 10 | echo "PATH: $PATH" 11 | rustc --version 12 | cargo --version 13 | echo 14 | echo "Environment variables:" 15 | env 16 | 17 | # vim: set ts=4 sw=4 et: 18 | -------------------------------------------------------------------------------- /protobuf-test/src/common/v2/test_ident.rs: -------------------------------------------------------------------------------- 1 | use super::test_ident_pb::*; 2 | use protobuf::Message; 3 | 4 | #[test] 5 | fn test() { 6 | let _ = TestType::new(); 7 | } 8 | 9 | #[test] 10 | fn test_reflect() { 11 | message_Self::new(); 12 | // instantiate reflection 13 | assert_eq!("Self", message_Self::descriptor_static().name()); 14 | } 15 | -------------------------------------------------------------------------------- /protobuf-test/src/common/v2/test_lite_runtime.rs: -------------------------------------------------------------------------------- 1 | use protobuf_test_common::*; 2 | 3 | use super::test_lite_runtime_pb::*; 4 | 5 | #[test] 6 | fn test_lite_runtime() { 7 | let mut m = TestLiteRuntime::new(); 8 | m.set_v(10); 9 | test_serialize_deserialize("08 0a", &m); 10 | 11 | // test it doesn't crash 12 | format!("{:?}", m); 13 | } 14 | -------------------------------------------------------------------------------- /protobuf-fuzz/build.rs: -------------------------------------------------------------------------------- 1 | extern crate protobuf_test_common; 2 | extern crate protoc_rust; 3 | 4 | fn main() { 5 | protobuf_test_common::build::clean_old_files(); 6 | 7 | protoc_rust::Args::new() 8 | .out_dir("src") 9 | .include("src") 10 | .input("src/all_types_pb.proto") 11 | .run() 12 | .expect("protoc_rust"); 13 | } 14 | -------------------------------------------------------------------------------- /protobuf-test/src/common/v2/test_enable_lite_runtime.rs: -------------------------------------------------------------------------------- 1 | use protobuf_test_common::*; 2 | 3 | use super::test_enable_lite_runtime_pb::*; 4 | 5 | #[test] 6 | fn test_lite_runtime() { 7 | let mut m = TestLiteRuntime::new(); 8 | m.set_v(10); 9 | test_serialize_deserialize("08 0a", &m); 10 | 11 | // test it doesn't crash 12 | format!("{:?}", m); 13 | } 14 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [workspace] 2 | members = [ 3 | "protoc", 4 | "protoc/test-protoc", 5 | "protoc-rust", 6 | "protobuf", 7 | "protobuf-fuzz", 8 | "protobuf-codegen", 9 | "protobuf-codegen-pure", 10 | "protobuf-codegen-pure-test", 11 | "protobuf-test", 12 | "protobuf-test-common", 13 | "perftest/vs-cxx", 14 | "perftest/bytes", 15 | ] 16 | -------------------------------------------------------------------------------- /protobuf-codegen/src/inside.rs: -------------------------------------------------------------------------------- 1 | use crate::customize::Customize; 2 | 3 | /// Path to `protobuf` crate, different when `.proto` file is 4 | /// used inside or outside of protobuf crate. 5 | pub(crate) fn protobuf_crate_path(customize: &Customize) -> &str { 6 | match customize.inside_protobuf { 7 | Some(true) => "crate", 8 | _ => "::protobuf", 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /protobuf-test/src/common/v2/test_generate_accessors.rs: -------------------------------------------------------------------------------- 1 | use super::test_generate_accessors_pb::*; 2 | 3 | #[test] 4 | fn test() { 5 | // Check accessors are generated 6 | WithAccessors::new().get_f(); 7 | WithAccessors::new().set_i(10); 8 | 9 | // Check that field is public 10 | // even if it's not requested explicitly 11 | WithoutAccessors::new().f; 12 | } 13 | -------------------------------------------------------------------------------- /protobuf-test/src/v3/test_ident_pb.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | message Vec { } 4 | 5 | message String { } 6 | 7 | message Option { } 8 | message None { } 9 | message Some { } 10 | 11 | message Message { } 12 | 13 | message TestType { 14 | oneof type { 15 | string s = 1; 16 | } 17 | repeated string struct = 2; 18 | repeated uint32 ref = 3; 19 | } 20 | -------------------------------------------------------------------------------- /protobuf/src/text_format/lexer/int.rs: -------------------------------------------------------------------------------- 1 | pub struct Overflow; 2 | 3 | /// Negate `u64` checking for overflow. 4 | pub fn neg(value: u64) -> Result { 5 | if value <= 0x7fff_ffff_ffff_ffff { 6 | Ok(-(value as i64)) 7 | } else if value == 0x8000_0000_0000_0000 { 8 | Ok(-0x8000_0000_0000_0000) 9 | } else { 10 | Err(Overflow) 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /protobuf-test/src/v3/test_zeros_are_not_written.rs: -------------------------------------------------------------------------------- 1 | use protobuf_test_common::*; 2 | 3 | use super::test_zeros_are_not_written_pb::*; 4 | 5 | #[test] 6 | fn test_zeros_are_not_written() { 7 | let mut m = TestZerosAreNotWritten::new(); 8 | m.bool_field = false; 9 | m.enum_field = TestEnumDescriptor::UNDEFINED.into(); 10 | m.fixed32_field = 0; 11 | test_serialize("", &m); 12 | } 13 | -------------------------------------------------------------------------------- /protobuf-codegen/src/syntax.rs: -------------------------------------------------------------------------------- 1 | #[derive(Debug, Copy, Clone, PartialEq, Eq)] 2 | pub enum Syntax { 3 | PROTO2, 4 | PROTO3, 5 | } 6 | 7 | impl Syntax { 8 | pub fn parse(s: &str) -> Self { 9 | match s { 10 | "" | "proto2" => Syntax::PROTO2, 11 | "proto3" => Syntax::PROTO3, 12 | _ => panic!("unsupported syntax value: {:?}", s), 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /protobuf-test/src/common/v2/test_lite_runtime_pb.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto2"; 2 | 3 | import "rustproto.proto"; 4 | option (rustproto.generate_accessors_all) = true; 5 | 6 | 7 | package test_lite_runtime; 8 | 9 | option optimize_for = LITE_RUNTIME; 10 | 11 | enum EnumTestLiteRuntime { 12 | UNKNOWN = 0; 13 | ONE = 1; 14 | TWO = 2; 15 | } 16 | 17 | message TestLiteRuntime { 18 | optional int32 v = 1; 19 | } 20 | -------------------------------------------------------------------------------- /protobuf-test/src/common/v2/test_map_carllerche_pb.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto2"; 2 | 3 | import "rustproto.proto"; 4 | 5 | option (rustproto.carllerche_bytes_for_bytes_all) = true; 6 | option (rustproto.carllerche_bytes_for_string_all) = true; 7 | 8 | message TestMapCarllerche { 9 | map string_to_int32 = 1; 10 | map int32_to_string = 2; 11 | map int32_to_bytes = 3; 12 | } 13 | -------------------------------------------------------------------------------- /protobuf-codegen/src/file_descriptor.rs: -------------------------------------------------------------------------------- 1 | use crate::rust_name::RustIdent; 2 | use crate::scope::Scope; 3 | 4 | pub(crate) fn file_descriptor_proto_expr(scope: &Scope) -> String { 5 | let file_descriptor_proto_path = scope 6 | .rust_path_to_file() 7 | .to_reverse() 8 | .into_path() 9 | .append_ident(RustIdent::from("file_descriptor_proto")); 10 | format!("{}()", file_descriptor_proto_path) 11 | } 12 | -------------------------------------------------------------------------------- /protobuf-test/src/common/v2/test_enum_alias_pb.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto2"; 2 | 3 | import "rustproto.proto"; 4 | option (rustproto.generate_accessors_all) = true; 5 | 6 | 7 | package test_enum_alias; 8 | 9 | enum EnumWithAlias { 10 | option allow_alias = true; 11 | UNKNOWN = 0; 12 | A = 10; 13 | B = 20; 14 | A_AGAIN = 10; 15 | } 16 | 17 | message TestEnumWithAlias { 18 | optional EnumWithAlias en = 1; 19 | } 20 | -------------------------------------------------------------------------------- /protobuf-test/src/common/v2/test_enable_lite_runtime_pb.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto2"; 2 | 3 | import "rustproto.proto"; 4 | option (rustproto.generate_accessors_all) = true; 5 | option (rustproto.lite_runtime_all) = true; 6 | 7 | 8 | package test_enable_lite_runtime; 9 | 10 | enum EnumTestLiteRuntime { 11 | UNKNOWN = 0; 12 | ONE = 1; 13 | TWO = 2; 14 | } 15 | 16 | message TestLiteRuntime { 17 | optional int32 v = 1; 18 | } 19 | -------------------------------------------------------------------------------- /protobuf-test/src/common/v2/test_repeated_packed_pb.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto2"; 2 | 3 | message TestPacked { 4 | repeated int32 varints = 4 [packed=true]; 5 | repeated sfixed32 sfixed32s = 5 [packed=true]; 6 | } 7 | 8 | message TestUnpacked { 9 | repeated int32 varints = 4 [packed=false]; 10 | repeated sfixed32 sfixed32s = 5 [packed=false]; 11 | } 12 | 13 | message TestIssue281 { 14 | repeated fixed32 values = 1 [packed=true]; 15 | } 16 | -------------------------------------------------------------------------------- /protobuf-test/src/common/v2/test_enum_values.rs: -------------------------------------------------------------------------------- 1 | use protobuf::*; 2 | 3 | use super::test_enum_values_pb::*; 4 | 5 | #[test] 6 | fn test_enum_values() { 7 | let expected = [ 8 | TestEnumValuesEnum::UNKNOWN, 9 | TestEnumValuesEnum::WINTER, 10 | TestEnumValuesEnum::SPRING, 11 | TestEnumValuesEnum::SUMMER, 12 | TestEnumValuesEnum::AUTUMN, 13 | ]; 14 | assert_eq!(expected, TestEnumValuesEnum::values()); 15 | } 16 | -------------------------------------------------------------------------------- /protobuf-codegen-pure-test/src/lib.rs: -------------------------------------------------------------------------------- 1 | #![cfg(test)] 2 | 3 | extern crate protobuf; 4 | 5 | extern crate protobuf_test_common; 6 | 7 | #[cfg(feature = "with-bytes")] 8 | extern crate bytes; 9 | 10 | #[cfg(feature = "with-serde")] 11 | extern crate serde; 12 | #[cfg(feature = "with-serde")] 13 | #[macro_use] 14 | extern crate serde_derive; 15 | #[cfg(feature = "with-serde")] 16 | extern crate serde_json; 17 | 18 | mod v2; 19 | mod v3; 20 | 21 | mod common; 22 | 23 | mod interop; 24 | -------------------------------------------------------------------------------- /protobuf-test/src/v2/test_carllerche_bytes_default_value_pb.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto2"; 2 | 3 | package test_carllerche_bytes_default_value; 4 | 5 | import "rustproto.proto"; 6 | 7 | option (rustproto.carllerche_bytes_for_bytes_all) = true; 8 | option (rustproto.carllerche_bytes_for_string_all) = true; 9 | option (rustproto.generate_accessors_all) = true; 10 | 11 | message TestCarllercheBytesDefaultValues { 12 | optional string s = 1 [default = "sss"]; 13 | optional bytes b = 2 [default = "bbb"]; 14 | } 15 | -------------------------------------------------------------------------------- /protobuf-test/src/common/v2/test_map_simple_pb.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto2"; 2 | 3 | package test_map_simple; 4 | 5 | import "rustproto.proto"; 6 | option (rustproto.generate_accessors_all) = true; 7 | 8 | 9 | message TestMap { 10 | map m = 1; 11 | map mm = 2; 12 | // just check it compiles 13 | map me = 3; 14 | } 15 | 16 | message TestMapEntry { 17 | optional int64 v = 1; 18 | } 19 | 20 | enum TestMapEnum { 21 | UNKNOWN = 0; 22 | ONE = 1; 23 | } 24 | -------------------------------------------------------------------------------- /protobuf-test/src/v2/test_carllerche_bytes_default_value.rs: -------------------------------------------------------------------------------- 1 | use protobuf::*; 2 | 3 | use super::test_carllerche_bytes_default_value_pb::*; 4 | 5 | #[test] 6 | fn test_default_values() { 7 | assert_eq!("sss", TestCarllercheBytesDefaultValues::default_instance().get_s()); 8 | assert_eq!(b"bbb", TestCarllercheBytesDefaultValues::default_instance().get_b()); 9 | assert_eq!(&""[..], &**TestCarllercheBytesDefaultValues::new().mut_s()); 10 | assert_eq!(&b""[..], &**TestCarllercheBytesDefaultValues::new().mut_b()); 11 | } 12 | -------------------------------------------------------------------------------- /protobuf-codegen-pure/src/bin/parse-and-typecheck.rs: -------------------------------------------------------------------------------- 1 | extern crate protobuf_codegen_pure; 2 | 3 | use std::env; 4 | use std::path::PathBuf; 5 | 6 | fn main() { 7 | let args = env::args_os().skip(1).map(PathBuf::from).collect::>(); 8 | assert!(args.len() >= 2); 9 | let (input, includes) = args.split_at(1); 10 | let t = 11 | protobuf_codegen_pure::parse_and_typecheck(includes, input).expect("parse_and_typecheck"); 12 | for fd in t.file_descriptors { 13 | println!("{:#?}", fd); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /protobuf-test-common/src/lib.rs: -------------------------------------------------------------------------------- 1 | //! Functions used in protobuf tests 2 | 3 | extern crate glob; 4 | extern crate protobuf; 5 | extern crate protobuf_codegen; 6 | #[macro_use] 7 | extern crate log; 8 | extern crate tempfile; 9 | 10 | pub mod build; 11 | pub mod hex; 12 | 13 | mod serialize_deserialize_tests; 14 | pub use serialize_deserialize_tests::*; 15 | 16 | mod text_format_tests; 17 | pub use text_format_tests::*; 18 | 19 | mod json_tests; 20 | pub use json_tests::*; 21 | 22 | mod reflect_tests; 23 | pub use reflect_tests::*; 24 | -------------------------------------------------------------------------------- /perftest/bytes/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "perftest-bytes" 3 | version = "0.0.0" 4 | authors = ["Stepan Koltsov "] 5 | publish = false 6 | edition = "2018" 7 | 8 | [lib] 9 | test = false 10 | doctest = false 11 | 12 | [features] 13 | default = [] 14 | with-bytes = ["bytes", "protobuf/with-bytes"] 15 | 16 | [dependencies] 17 | bytes = { version = "0.4", optional = true } 18 | 19 | [dependencies.protobuf] 20 | path = "../../protobuf" 21 | 22 | [build-dependencies] 23 | protoc-rust = { path = "../../protoc-rust" } 24 | -------------------------------------------------------------------------------- /protobuf-codegen/src/serde.rs: -------------------------------------------------------------------------------- 1 | use crate::code_writer::CodeWriter; 2 | use crate::customize::Customize; 3 | 4 | /// Write serde attr according to specified codegen option. 5 | pub fn write_serde_attr(w: &mut CodeWriter, customize: &Customize, attr: &str) { 6 | if customize.serde_derive.unwrap_or(false) { 7 | if let Some(ref cfg) = customize.serde_derive_cfg { 8 | w.write_line(&format!("#[cfg_attr({}, {})]", cfg, attr)); 9 | } else { 10 | w.write_line(&format!("#[{}]", attr)); 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /protobuf-test/src/common/v2/test_carllerche_bytes_pb.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto2"; 2 | 3 | import "rustproto.proto"; 4 | 5 | option (rustproto.carllerche_bytes_for_bytes_all) = true; 6 | option (rustproto.carllerche_bytes_for_string_all) = true; 7 | option (rustproto.generate_accessors_all) = true; 8 | 9 | message TestCarllercheBytes { 10 | optional bytes b1 = 1; 11 | optional string s1 = 2; 12 | repeated bytes br = 3; 13 | repeated string sr = 4; 14 | oneof one { 15 | bytes ob = 11; 16 | string os = 12; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /protoc/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "protoc" 3 | version = "3.0.0-pre" 4 | edition = "2018" 5 | authors = ["Stepan Koltsov "] 6 | license = "MIT" 7 | homepage = "https://github.com/stepancheg/rust-protobuf/tree/master/protoc/" 8 | repository = "https://github.com/stepancheg/rust-protobuf/tree/master/protoc/" 9 | description = """ 10 | Protobuf protoc command as API 11 | """ 12 | 13 | [lib] 14 | doctest = false 15 | bench = false 16 | 17 | [dependencies] 18 | log = "0.*" 19 | 20 | [package.metadata.docs.rs] 21 | all-features = true 22 | -------------------------------------------------------------------------------- /protoc/test-protoc/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "test-protoc" 3 | version = "0.0.0" 4 | publish = false 5 | edition = "2018" 6 | authors = ["Stepan Koltsov "] 7 | 8 | [lib] 9 | test = false 10 | doctest = false 11 | bench = false 12 | 13 | [dependencies] 14 | protobuf = { path = "../../protobuf" } 15 | 16 | [features] 17 | default = [] 18 | # Feature to avoid recompilation of protobuf 19 | with-bytes = ["protobuf/with-bytes"] 20 | with-serde = ["protobuf/with-serde"] 21 | 22 | [build-dependencies] 23 | protoc = { path = ".." } 24 | -------------------------------------------------------------------------------- /protobuf-test/src/common/v2/test_singular_field_option.rs: -------------------------------------------------------------------------------- 1 | use super::test_singular_field_option_pb::*; 2 | use protobuf::SingularPtrField; 3 | 4 | #[test] 5 | fn test_option_box() { 6 | let w = WithOptionBox::new(); 7 | let _inner: &Option> = &w.inner; 8 | } 9 | 10 | #[test] 11 | fn test_option() { 12 | let w = WithOption::new(); 13 | let _inner: &Option = &w.inner; 14 | } 15 | 16 | #[test] 17 | fn test_singular_ptr_field() { 18 | let w = WithSingularField::new(); 19 | let _inner: &SingularPtrField = &w.inner; 20 | } 21 | -------------------------------------------------------------------------------- /protobuf-test/src/google/protobuf/import-tests.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh -e 2 | 3 | cd $(dirname $0) 4 | 5 | rm -rf *.proto protobuf-git 6 | 7 | git clone --branch v3.5.2 --depth 1 https://github.com/google/protobuf/ protobuf-git 8 | 9 | cp protobuf-git/src/google/protobuf/unittest*.proto ./ 10 | 11 | rm -rf protobuf-git 12 | 13 | # This file causes memory overflow in `rustc` when executed on travis-ci 14 | rm unittest_enormous_descriptor.proto 15 | 16 | # These files duplicate similar files for proto2 and cannot be compiled together 17 | rm *_proto3.proto 18 | 19 | # vim: set ts=4 sw=4 et: 20 | -------------------------------------------------------------------------------- /protoc/README.md: -------------------------------------------------------------------------------- 1 | # Protoc command launcher 2 | 3 | API to invoke `protoc` command from API (e. g. from `build.rs`), any 4 | 5 | Note, `protoc` command must be in `$PATH` along with `protoc-gen-LANG` command. 6 | 7 | Example of using `protoc` crate is in perftest's 8 | [build.rs](https://github.com/stepancheg/rust-protobuf/blob/master/perftest/build.rs). 9 | 10 | Note that to generate `rust` code from `.proto`, 11 | [protoc-rust](https://github.com/stepancheg/rust-protobuf/tree/master/protoc-rust) crate can be used, 12 | which does not require `protoc-gen-rust` present in `$PATH`. 13 | -------------------------------------------------------------------------------- /protobuf-test/src/lib.rs: -------------------------------------------------------------------------------- 1 | #![cfg(test)] 2 | 3 | extern crate protobuf; 4 | 5 | extern crate protobuf_test_common; 6 | 7 | #[cfg(feature = "with-bytes")] 8 | extern crate bytes; 9 | 10 | #[cfg(feature = "with-serde")] 11 | extern crate serde; 12 | #[cfg(feature = "with-serde")] 13 | #[macro_use] 14 | extern crate serde_derive; 15 | #[cfg(feature = "with-serde")] 16 | extern crate serde_json; 17 | 18 | mod v2; 19 | 20 | // `cfg(proto3)` is emitted by `build.rs` 21 | 22 | #[cfg(proto3)] 23 | mod v3; 24 | 25 | mod common; 26 | 27 | #[cfg(proto3)] 28 | mod google; 29 | 30 | mod interop; 31 | -------------------------------------------------------------------------------- /protobuf-test/src/common/v2/test_repeated_field_vec.rs: -------------------------------------------------------------------------------- 1 | use super::test_repeated_field_vec_pb::*; 2 | use protobuf::RepeatedField; 3 | 4 | #[test] 5 | fn test_vec() { 6 | let basket = BasketVec::new(); 7 | let _eggs: Vec = basket.eggs; 8 | let _s: Vec = basket.s; 9 | let _b: Vec> = basket.b; 10 | } 11 | 12 | #[test] 13 | fn test_repeated_field() { 14 | let basket = BasketRepeatedField::new(); 15 | let _eggs: RepeatedField = basket.eggs; 16 | let _s: RepeatedField = basket.s; 17 | let _b: RepeatedField> = basket.b; 18 | } 19 | -------------------------------------------------------------------------------- /protobuf/src/json/json_name.rs: -------------------------------------------------------------------------------- 1 | /// Implementation must match exactly 2 | /// `ToJsonName()` function in C++ `descriptor.cc`. 3 | pub(crate) fn json_name(input: &str) -> String { 4 | let mut capitalize_next = false; 5 | let mut result = String::with_capacity(input.len()); 6 | 7 | for c in input.chars() { 8 | if c == '_' { 9 | capitalize_next = true; 10 | } else if capitalize_next { 11 | result.extend(c.to_uppercase()); 12 | capitalize_next = false; 13 | } else { 14 | result.push(c); 15 | } 16 | } 17 | 18 | result 19 | } 20 | -------------------------------------------------------------------------------- /protobuf-test/src/common/v2/test_singular_concat.rs: -------------------------------------------------------------------------------- 1 | //! Test when two messages are concatenated, singular fields are taken from the last one. 2 | 3 | use super::test_singular_concat_pb::*; 4 | 5 | use protobuf_test_common::*; 6 | 7 | #[test] 8 | fn test_concat_bytes() { 9 | let mut m = TestSingularConcat::new(); 10 | m.set_b(b"\xdd\xee".to_vec()); 11 | 12 | test_deserialize("12 03 aa bb cc 12 02 dd ee", &m); 13 | } 14 | 15 | #[test] 16 | fn test_concat_string() { 17 | let mut m = TestSingularConcat::new(); 18 | m.set_s("\x61\x62".to_string()); 19 | 20 | test_deserialize("0a 03 21 22 23 0a 02 61 62", &m); 21 | } 22 | -------------------------------------------------------------------------------- /protobuf-test/src/common/v2/test_enum_unknown_values_preserved.rs: -------------------------------------------------------------------------------- 1 | use super::test_enum_unknown_values_preserved_pb::*; 2 | 3 | use protobuf::*; 4 | use protobuf_test_common::*; 5 | 6 | #[test] 7 | fn unknown_values_preserved() { 8 | let mut new = NewMessage::new(); 9 | new.set_eee(NewEnum::C); 10 | 11 | test_serialize_deserialize("08 1e", &new); 12 | 13 | // `OldEnum` doesn't have variant `C = 30`, 14 | // but message still properly serialized and deserialized. 15 | 16 | let old: OldMessage = parse_from_bytes(&hex::decode_hex("08 1e")).expect("parse"); 17 | 18 | test_serialize_deserialize("08 1e", &old); 19 | } 20 | -------------------------------------------------------------------------------- /protobuf-test/src/common/v2/test_enum_unknown_values_preserved_pb.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto2"; 2 | 3 | import "rustproto.proto"; 4 | option (rustproto.generate_accessors_all) = true; 5 | 6 | 7 | package unknown_values_preserved; 8 | 9 | enum OldEnum { 10 | // Add _OLD suffix to field name to avoid collision with NewEnum 11 | UNKNOWN_OLD = 0; 12 | A_OLD = 10; 13 | B_OLD = 20; 14 | } 15 | 16 | enum NewEnum { 17 | UNKNOWN = 0; 18 | A = 10; 19 | B = 20; 20 | C = 30; 21 | } 22 | 23 | message OldMessage { 24 | optional OldEnum eee = 1; 25 | } 26 | 27 | message NewMessage { 28 | optional NewEnum eee = 1; 29 | } 30 | -------------------------------------------------------------------------------- /perftest/vs-cxx/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "rust-protobuf-perftest" 3 | version = "0.0.0" 4 | authors = ["Stepan Koltsov "] 5 | publish = false 6 | edition = "2018" 7 | 8 | [features] 9 | default = [] 10 | proto3 = [] 11 | with-bytes = ["protobuf/with-bytes"] 12 | 13 | [dependencies.protobuf] 14 | path = "../../protobuf" 15 | 16 | [dependencies.time] 17 | git = "http://github.com/rust-lang/time" 18 | 19 | [dependencies] 20 | rand = "~0.5" 21 | 22 | [build-dependencies] 23 | protoc-rust = { path = "../../protoc-rust" } 24 | 25 | [[bin]] 26 | 27 | name = "rust-protobuf-perftest" 28 | path = "perftest.rs" 29 | test = false 30 | -------------------------------------------------------------------------------- /protobuf/src/text_format/lexer/loc.rs: -------------------------------------------------------------------------------- 1 | use std::fmt; 2 | 3 | pub const FIRST_LINE: u32 = 1; 4 | pub const FIRST_COL: u32 = 1; 5 | 6 | /// Location in file 7 | #[derive(Copy, Clone, Debug, Eq, PartialEq)] 8 | pub struct Loc { 9 | /// 1-based 10 | pub line: u32, 11 | /// 1-based 12 | pub col: u32, 13 | } 14 | 15 | impl fmt::Display for Loc { 16 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 17 | write!(f, "{}:{}", self.line, self.col) 18 | } 19 | } 20 | 21 | impl Loc { 22 | pub fn start() -> Loc { 23 | Loc { 24 | line: FIRST_LINE, 25 | col: FIRST_COL, 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /perftest/bytes/src/messages.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto2"; 2 | 3 | import "rustproto.proto"; 4 | 5 | message TestMessage { 6 | optional string s1 = 1; 7 | optional bytes b1 = 2; 8 | repeated string sr = 3; 9 | repeated bytes br = 4; 10 | 11 | optional TestMessage nested = 11; 12 | } 13 | 14 | message TestMessageWithBytes { 15 | option (rustproto.carllerche_bytes_for_bytes) = true; 16 | option (rustproto.carllerche_bytes_for_string) = true; 17 | 18 | optional string s1 = 1; 19 | optional bytes b1 = 2; 20 | repeated string sr = 3; 21 | repeated bytes br = 4; 22 | 23 | optional TestMessageWithBytes nested = 11; 24 | } 25 | -------------------------------------------------------------------------------- /protobuf-test/src/common/v2/test_carllerche_bytes.rs: -------------------------------------------------------------------------------- 1 | use bytes::Bytes; 2 | use protobuf::Chars; 3 | 4 | use super::test_carllerche_bytes_pb::*; 5 | 6 | use protobuf_test_common::*; 7 | 8 | #[test] 9 | fn test() { 10 | let mut m = TestCarllercheBytes::new(); 11 | m.set_b1(Bytes::from("aabb")); 12 | m.set_s1(Chars::from("ccdd")); 13 | 14 | let mut br = Vec::new(); 15 | br.push(Bytes::from("bb1")); 16 | br.push(Bytes::from("bb2")); 17 | m.set_br(br); 18 | 19 | let mut sr = Vec::new(); 20 | sr.push(Chars::from("ss1")); 21 | sr.push(Chars::from("ss2")); 22 | m.set_sr(sr); 23 | 24 | test_serialize_deserialize_no_hex(&m); 25 | } 26 | -------------------------------------------------------------------------------- /protobuf-test/src/common/v2/test_repeated_field_vec_pb.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto2"; 2 | 3 | import "rustproto.proto"; 4 | 5 | package test_repeated_field_vec; 6 | 7 | message Egg { 8 | optional int32 size = 1; 9 | } 10 | 11 | message BasketVec { 12 | option (rustproto.repeated_field_vec) = true; 13 | option (rustproto.expose_fields) = true; 14 | 15 | repeated Egg eggs = 1; 16 | repeated string s = 2; 17 | repeated bytes b = 3; 18 | } 19 | 20 | message BasketRepeatedField { 21 | option (rustproto.repeated_field_vec) = false; 22 | option (rustproto.expose_fields) = true; 23 | 24 | repeated Egg eggs = 1; 25 | repeated string s = 2; 26 | repeated bytes b = 3; 27 | } 28 | -------------------------------------------------------------------------------- /protobuf-test/src/v2/test_required.rs: -------------------------------------------------------------------------------- 1 | use protobuf::prelude::*; 2 | use protobuf::*; 3 | 4 | use super::test_required_pb::*; 5 | 6 | #[test] 7 | #[should_panic] 8 | fn test_write_missing_required() { 9 | TestRequired::new().write_to_bytes().unwrap(); 10 | } 11 | 12 | #[test] 13 | #[should_panic] 14 | fn test_read_missing_required() { 15 | parse_from_bytes::(&[]).unwrap(); 16 | } 17 | 18 | #[test] 19 | fn test_is_initialized_is_recursive() { 20 | let mut m = TestRequiredOuter::new(); 21 | assert!(!m.is_initialized()); 22 | m.inner.set_message(Default::default()); 23 | assert!(!m.is_initialized()); 24 | m.inner.as_mut().unwrap().set_b(false); 25 | assert!(m.is_initialized()); 26 | } 27 | -------------------------------------------------------------------------------- /protobuf/src/clear.rs: -------------------------------------------------------------------------------- 1 | #[cfg(feature = "bytes")] 2 | use bytes::Bytes; 3 | 4 | /// anything that can be cleared 5 | pub trait Clear { 6 | /// Clear this make, make it equivalent to newly created object. 7 | fn clear(&mut self); 8 | } 9 | 10 | impl Clear for Option { 11 | fn clear(&mut self) { 12 | self.take(); 13 | } 14 | } 15 | 16 | impl Clear for String { 17 | fn clear(&mut self) { 18 | String::clear(self); 19 | } 20 | } 21 | 22 | impl Clear for Vec { 23 | fn clear(&mut self) { 24 | Vec::clear(self); 25 | } 26 | } 27 | 28 | #[cfg(feature = "bytes")] 29 | impl Clear for Bytes { 30 | fn clear(&mut self) { 31 | Bytes::clear(self); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /protobuf/src/reflect/accessor/mod.rs: -------------------------------------------------------------------------------- 1 | use crate::reflect::accessor::singular::SingularFieldAccessorHolder; 2 | use crate::reflect::accessor::repeated::RepeatedFieldAccessorHolder; 3 | use crate::reflect::accessor::map::MapFieldAccessorHolder; 4 | 5 | pub(crate) mod map; 6 | pub(crate) mod repeated; 7 | pub(crate) mod singular; 8 | 9 | pub(crate) enum AccessorKind { 10 | Singular(SingularFieldAccessorHolder), 11 | Repeated(RepeatedFieldAccessorHolder), 12 | Map(MapFieldAccessorHolder), 13 | } 14 | 15 | /// Accessor object is constructed in generated code. 16 | /// Should not be used directly. 17 | pub struct FieldAccessor { 18 | pub(crate) name: &'static str, 19 | pub(crate) accessor: AccessorKind, 20 | } 21 | -------------------------------------------------------------------------------- /protobuf/src/well_known_types/mod.rs: -------------------------------------------------------------------------------- 1 | // This file is generated. Do not edit 2 | //! Generated code for "well known types" 3 | //! 4 | //! [This document](https://developers.google.com/protocol-buffers/docs/reference/google.protobuf) describes these types. 5 | 6 | mod any; 7 | mod api; 8 | mod duration; 9 | mod empty; 10 | mod field_mask; 11 | mod source_context; 12 | mod struct_pb; 13 | mod timestamp; 14 | mod type_pb; 15 | mod wrappers; 16 | 17 | pub use self::any::*; 18 | pub use self::api::*; 19 | pub use self::duration::*; 20 | pub use self::empty::*; 21 | pub use self::field_mask::*; 22 | pub use self::source_context::*; 23 | pub use self::struct_pb::*; 24 | pub use self::timestamp::*; 25 | pub use self::type_pb::*; 26 | pub use self::wrappers::*; 27 | -------------------------------------------------------------------------------- /protobuf-test/src/common/v2/test_generate_accessors_pb.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto2"; 2 | 3 | import "rustproto.proto"; 4 | 5 | package test_generate_accessors; 6 | 7 | message FooBar {} 8 | 9 | message WithAccessors { 10 | option (rustproto.generate_accessors) = true; 11 | 12 | optional int32 i = 1; 13 | optional string s = 2; 14 | optional FooBar f = 3; 15 | repeated int32 is = 11; 16 | optional string ss = 12; 17 | optional FooBar fs = 13; 18 | } 19 | 20 | message WithoutAccessors { 21 | option (rustproto.generate_accessors) = false; 22 | 23 | optional int32 i = 1; 24 | optional string s = 2; 25 | optional FooBar f = 3; 26 | repeated int32 is = 11; 27 | optional string ss = 12; 28 | optional FooBar fs = 13; 29 | } 30 | -------------------------------------------------------------------------------- /protobuf/src/reflect/runtime_type_box.rs: -------------------------------------------------------------------------------- 1 | use crate::reflect::EnumDescriptor; 2 | use crate::reflect::MessageDescriptor; 3 | 4 | /// Runtime representation of elementary protobuf type. 5 | pub enum RuntimeTypeBox { 6 | /// `i32` 7 | I32, 8 | /// `i64` 9 | I64, 10 | /// `u32` 11 | U32, 12 | /// `u64` 13 | U64, 14 | /// `f32` 15 | F32, 16 | /// `f64` 17 | F64, 18 | /// `bool` 19 | Bool, 20 | /// [`String`](std::string::String) 21 | String, 22 | /// `Chars` 23 | Chars, 24 | /// [`Vec`](std::vec::Vec) 25 | VecU8, 26 | /// `Bytes` 27 | CarllercheBytes, 28 | /// `enum` 29 | Enum(&'static EnumDescriptor), 30 | /// `message` 31 | Message(&'static MessageDescriptor), 32 | } 33 | -------------------------------------------------------------------------------- /proto/google/protobuf/fetch-protos.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh -ex 2 | 3 | # fetch protos from protobuf respository 4 | # comment out `reserved` directive for comatibility with protobuf 2.6.1 5 | # https://github.com/google/protobuf/issues/1669#issuecomment-240598089 6 | for f in descriptor.proto compiler/plugin.proto \ 7 | any.proto \ 8 | api.proto \ 9 | duration.proto \ 10 | empty.proto \ 11 | field_mask.proto \ 12 | source_context.proto \ 13 | struct.proto \ 14 | timestamp.proto \ 15 | type.proto \ 16 | wrappers.proto \ 17 | ; do 18 | curl -s https://raw.githubusercontent.com/google/protobuf/v3.1.0/src/google/protobuf/$f \ 19 | | sed -e 's,^\( *\)\(reserved.*\),\1// \2,' \ 20 | > $f 21 | done 22 | 23 | # vim: set ts=4 sw=4 et: 24 | -------------------------------------------------------------------------------- /protobuf-test/src/v3/test_zeros_are_not_written_pb.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | enum TestEnumDescriptor { 4 | UNDEFINED = 0; 5 | RED = 1; 6 | BLUE = 2; 7 | GREEN = 3; 8 | } 9 | 10 | message TestZerosAreNotWritten { 11 | double double_field = 1; 12 | float float_field = 2; 13 | int32 int32_field = 3; 14 | int64 int64_field = 4; 15 | uint32 uint32_field = 5; 16 | uint64 uint64_field = 6; 17 | sint32 sint32_field = 7; 18 | sint64 sint64_field = 8; 19 | fixed32 fixed32_field = 9; 20 | fixed64 fixed64_field = 10; 21 | sfixed32 sfixed32_field = 11; 22 | sfixed64 sfixed64_field = 12; 23 | bool bool_field = 13; 24 | string string_field = 14; 25 | bytes bytes_field = 15; 26 | TestEnumDescriptor enum_field = 16; 27 | } 28 | 29 | -------------------------------------------------------------------------------- /protobuf-test/src/common/v2/test_enum_alias.rs: -------------------------------------------------------------------------------- 1 | use protobuf::ProtobufEnum; 2 | 3 | use super::test_enum_alias_pb::*; 4 | 5 | use protobuf_test_common::*; 6 | 7 | #[test] 8 | fn test_enum() { 9 | assert_eq!(10, EnumWithAlias::A.value()); 10 | assert_eq!(10, EnumWithAlias::A_AGAIN.value()); 11 | assert_eq!( 12 | &[ 13 | EnumWithAlias::UNKNOWN, 14 | EnumWithAlias::A, 15 | EnumWithAlias::B, 16 | EnumWithAlias::A_AGAIN, 17 | ], 18 | EnumWithAlias::values() 19 | ); 20 | assert_eq!(EnumWithAlias::A, EnumWithAlias::A_AGAIN); 21 | } 22 | 23 | #[test] 24 | fn test_enum_in_message() { 25 | let mut m = TestEnumWithAlias::new(); 26 | m.set_en(EnumWithAlias::A); 27 | test_serialize_deserialize("08 0a", &m); 28 | } 29 | -------------------------------------------------------------------------------- /protobuf/src/json/mod.rs: -------------------------------------------------------------------------------- 1 | //! JSON printer and parser which tries to follow 2 | //! [protobuf conventions](https://developers.google.com/protocol-buffers/docs/proto3#json) 3 | 4 | mod base64; 5 | mod float; 6 | mod json_name; 7 | mod parse; 8 | mod print; 9 | mod rfc_3339; 10 | mod well_known_wrapper; 11 | 12 | pub(crate) use self::json_name::json_name; 13 | pub use self::parse::merge_from_str; 14 | pub use self::parse::merge_from_str_with_options; 15 | pub use self::parse::parse_dynamic_from_str; 16 | pub use self::parse::parse_dynamic_from_str_with_options; 17 | pub use self::parse::parse_from_str; 18 | pub use self::parse::parse_from_str_with_options; 19 | pub use self::parse::ParseOptions; 20 | pub use self::print::print_to_string; 21 | pub use self::print::print_to_string_with_options; 22 | pub use self::print::PrintOptions; 23 | -------------------------------------------------------------------------------- /protobuf/src/text_format/lexer/mod.rs: -------------------------------------------------------------------------------- 1 | //! Implementation of lexer for both protobuf parser and for text format parser. 2 | 3 | pub mod float; 4 | pub mod int; 5 | mod json_number_lit; 6 | mod lexer_impl; 7 | mod loc; 8 | mod num_lit; 9 | mod parser_language; 10 | mod str_lit; 11 | mod token; 12 | mod tokenizer; 13 | 14 | pub use self::json_number_lit::JsonNumberLit; 15 | pub use self::lexer_impl::Lexer; 16 | pub use self::lexer_impl::LexerError; 17 | pub use self::loc::Loc; 18 | pub use self::num_lit::NumLit; 19 | pub use self::parser_language::ParserLanguage; 20 | pub use self::str_lit::StrLit; 21 | pub use self::str_lit::StrLitDecodeError; 22 | pub use self::token::Token; 23 | pub use self::token::TokenWithLocation; 24 | pub use self::tokenizer::Tokenizer; 25 | pub use self::tokenizer::TokenizerError; 26 | pub use self::tokenizer::TokenizerResult; 27 | -------------------------------------------------------------------------------- /protoc-rust/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "protoc-rust" 3 | version = "3.0.0-pre" 4 | edition = "2018" 5 | authors = ["Stepan Koltsov "] 6 | license = "MIT" 7 | homepage = "https://github.com/stepancheg/rust-protobuf/tree/master/protoc-rust/" 8 | repository = "https://github.com/stepancheg/rust-protobuf/tree/master/protoc-rust/" 9 | description = """ 10 | protoc --rust_out=... available as API. protoc needs to be in $PATH, protoc-gen-run does not. 11 | """ 12 | 13 | [lib] 14 | doctest = false 15 | bench = false 16 | 17 | [dependencies] 18 | protoc = { path = "../protoc", version = "=3.0.0-pre" } 19 | protobuf = { path = "../protobuf", version = "=3.0.0-pre" } 20 | protobuf-codegen = { path = "../protobuf-codegen", version = "=3.0.0-pre" } 21 | tempfile = "3" 22 | 23 | [package.metadata.docs.rs] 24 | all-features = true 25 | -------------------------------------------------------------------------------- /protobuf-test/src/common/v2/test_well_known_types_pb.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto2"; 2 | 3 | import "google/protobuf/any.proto"; 4 | import "google/protobuf/api.proto"; 5 | import "google/protobuf/duration.proto"; 6 | import "google/protobuf/empty.proto"; 7 | import "google/protobuf/field_mask.proto"; 8 | import "google/protobuf/source_context.proto"; 9 | import "google/protobuf/struct.proto"; 10 | import "google/protobuf/timestamp.proto"; 11 | import "google/protobuf/type.proto"; 12 | import "google/protobuf/wrappers.proto"; 13 | 14 | // generate accessors to make sure accessors are generated correctly 15 | import "rustproto.proto"; 16 | option (rustproto.generate_accessors_all) = true; 17 | 18 | message UsesWellKnownTypes { 19 | optional .google.protobuf.NullValue null_value = 3; 20 | // remaining types are covered by `unittest_well_known_types.proto` 21 | } 22 | -------------------------------------------------------------------------------- /protobuf/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | 3 | name = "protobuf" 4 | version = "3.0.0-pre" 5 | authors = ["Stepan Koltsov "] 6 | edition = "2018" 7 | license = "MIT" 8 | homepage = "https://github.com/stepancheg/rust-protobuf/" 9 | repository = "https://github.com/stepancheg/rust-protobuf/" 10 | documentation = "https://github.com/stepancheg/rust-protobuf/blob/master/README.md" 11 | description = """ 12 | Rust implementation of Google protocol buffers 13 | """ 14 | 15 | [lib] 16 | bench = false 17 | 18 | [features] 19 | with-bytes = ["bytes"] 20 | with-serde = ["serde", "serde_derive"] 21 | default = [] 22 | 23 | [dependencies] 24 | bytes = { version = "0.4", optional = true } 25 | serde = { version = "1.0", optional = true } 26 | serde_derive = { version = "1.0", optional = true } 27 | 28 | [package.metadata.docs.rs] 29 | all-features = true 30 | -------------------------------------------------------------------------------- /protobuf-codegen-pure/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "protobuf-codegen-pure" 3 | version = "3.0.0-pre" 4 | authors = ["Stepan Koltsov "] 5 | edition = "2018" 6 | license = "MIT" 7 | homepage = "https://github.com/stepancheg/rust-protobuf/tree/master/protobuf-codegen-pure/" 8 | repository = "https://github.com/stepancheg/rust-protobuf/tree/master/protobuf-codegen-pure/" 9 | description = """ 10 | Pure-rust codegen for protobuf using protobuf-parser crate 11 | 12 | WIP 13 | """ 14 | 15 | [lib] 16 | doctest = false 17 | bench = false 18 | 19 | [dependencies] 20 | protobuf = { path = "../protobuf", version = "=3.0.0-pre" } 21 | protobuf-codegen = { path = "../protobuf-codegen", version = "=3.0.0-pre" } 22 | 23 | [[bin]] 24 | 25 | name = "parse-and-typecheck" 26 | path = "src/bin/parse-and-typecheck.rs" 27 | test = false 28 | 29 | [package.metadata.docs.rs] 30 | all-features = true 31 | -------------------------------------------------------------------------------- /protobuf-fuzz/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "protobuf-fuzz" 3 | version = "0.0.0" 4 | authors = ["Stepan Koltsov "] 5 | publish = false 6 | edition = "2018" 7 | 8 | [lib] 9 | doctest = false 10 | bench = false 11 | 12 | [features] 13 | default = [] 14 | proto3 = [] 15 | with-bytes = ["bytes", "protobuf/with-bytes", "protobuf-test-common/with-bytes"] 16 | 17 | [build-dependencies] 18 | protoc = { path = "../protoc" } 19 | protoc-rust = { path = "../protoc-rust" } 20 | protobuf-test-common = { path = "../protobuf-test-common" } 21 | glob = "0.2" 22 | log = "0.*" 23 | env_logger = "0.5.*" 24 | 25 | [dependencies] 26 | protobuf-test-common = { path = "../protobuf-test-common" } 27 | serde = "1.0" 28 | serde_derive = "1.0" 29 | serde_json = "1.0" 30 | bytes = { version = "0.4", optional = true } 31 | 32 | [dependencies.protobuf] 33 | path = "../protobuf" 34 | -------------------------------------------------------------------------------- /ci/run.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh -e 2 | 3 | ci/env-debug.sh 4 | if [ -z "$ON_WINDOWS" ]; then ccache --zero-stats; fi 5 | ci/install-protobuf.sh 6 | if [ -z "$ON_WINDOWS" ]; then ccache --show-stats; fi 7 | export PATH="$HOME/bin:$PATH" 8 | export LD_LIBRARY_PATH="$HOME/lib" 9 | which protoc 10 | protoc --version 11 | if [ -z "$ON_WINDOWS" ]; 12 | then PKG_CONFIG_PATH="$HOME/lib/pkgconfig" interop/cxx/compile.sh 13 | fi 14 | export RUST_BACKTRACE=1 15 | 16 | protobuf/regenerate.sh 17 | cargo test --all 18 | # `cargo test --all --features=FFF` doesn't work if there are crates without feature `FFF` 19 | # hence the explicit list of tests 20 | protobuf-test/test.sh 21 | protobuf-codegen-pure-test/test.sh 22 | protoc/test.sh 23 | cargo build --all --all-targets 24 | 25 | if [ -z "$ON_WINDOWS" ]; then 26 | cargo doc -p protobuf 27 | cargo doc -p protoc 28 | cargo doc -p protoc-rust 29 | fi 30 | 31 | # vim: set ts=4 sw=4 et: 32 | -------------------------------------------------------------------------------- /protobuf/src/paginate.rs: -------------------------------------------------------------------------------- 1 | pub trait PaginatableIterator: Sized { 2 | fn paginate(self, page: usize) -> Paginate; 3 | } 4 | 5 | impl> PaginatableIterator for U { 6 | fn paginate(self, page: usize) -> Paginate { 7 | Paginate { 8 | iter: self, 9 | page: page, 10 | } 11 | } 12 | } 13 | 14 | pub struct Paginate { 15 | iter: I, 16 | page: usize, 17 | } 18 | 19 | impl> Iterator for Paginate { 20 | type Item = Vec; 21 | 22 | fn next(&mut self) -> Option> { 23 | let mut r = Vec::new(); 24 | for _ in 0..self.page { 25 | match self.iter.next() { 26 | Some(next) => r.push(next), 27 | None if r.is_empty() => return None, 28 | None => return Some(r), 29 | } 30 | } 31 | Some(r) 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /protobuf-codegen/src/amend_io_error_util.rs: -------------------------------------------------------------------------------- 1 | use std::error::Error; 2 | use std::fmt; 3 | use std::io; 4 | 5 | #[derive(Debug)] 6 | struct IoErrorWithMessage { 7 | message: String, 8 | underlying: io::Error, 9 | } 10 | 11 | impl fmt::Display for IoErrorWithMessage { 12 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 13 | write!(f, "{}: {}", self.message, self.underlying) 14 | } 15 | } 16 | 17 | impl Error for IoErrorWithMessage { 18 | fn description(&self) -> &str { 19 | &self.message 20 | } 21 | 22 | fn cause(&self) -> Option<&Error> { 23 | Some(&self.underlying) 24 | } 25 | } 26 | 27 | pub fn amend_io_error>(error: io::Error, message: M) -> io::Error { 28 | io::Error::new( 29 | error.kind(), 30 | Box::new(IoErrorWithMessage { 31 | message: message.into(), 32 | underlying: error, 33 | }), 34 | ) 35 | } 36 | -------------------------------------------------------------------------------- /protobuf-codegen/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "protobuf-codegen" 3 | version = "3.0.0-pre" 4 | authors = ["Stepan Koltsov "] 5 | edition = "2018" 6 | license = "MIT" 7 | homepage = "https://github.com/stepancheg/rust-protobuf/" 8 | repository = "https://github.com/stepancheg/rust-protobuf/" 9 | description = """ 10 | Code generator for rust-protobuf. 11 | 12 | Includes a library and `protoc-gen-rust` binary. 13 | 14 | See `protoc-rust` and `protobuf-codegen-pure` crates. 15 | """ 16 | 17 | [lib] 18 | bench = false 19 | 20 | [dependencies] 21 | protobuf = { path = "../protobuf", version = "=3.0.0-pre" } 22 | 23 | [[bin]] 24 | 25 | name = "protoc-gen-rust" 26 | path = "src/bin/protoc-gen-rust.rs" 27 | test = false 28 | 29 | [[bin]] 30 | 31 | name = "protobuf-bin-gen-rust-do-not-use" 32 | path = "src/bin/protobuf-bin-gen-rust-do-not-use.rs" 33 | test = false 34 | 35 | [package.metadata.docs.rs] 36 | all-features = true 37 | -------------------------------------------------------------------------------- /protobuf-test-common/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "protobuf-test-common" 3 | version = "0.0.0" 4 | authors = ["Stepan Koltsov "] 5 | publish = false 6 | edition = "2018" 7 | description = """ 8 | Common code of protobuf tests 9 | """ 10 | 11 | [lib] 12 | doctest = false 13 | bench = false 14 | 15 | [features] 16 | default = [] 17 | proto3 = [] 18 | with-bytes = ["bytes", "protobuf/with-bytes"] 19 | with-serde = ["serde", "protobuf/with-serde"] 20 | 21 | [dependencies] 22 | glob = "0.2" 23 | log = "0.*" 24 | env_logger = "0.5.*" 25 | tempfile = "3.0" 26 | serde = { version = "1.0", optional = true } 27 | serde_derive = { version = "1.0", optional = true } 28 | serde_json = { version = "1.0", optional = true } 29 | bytes = { version = "0.4", optional = true } 30 | 31 | [dependencies.protobuf] 32 | path = "../protobuf" 33 | 34 | [dependencies.protobuf-codegen] 35 | path = "../protobuf-codegen" 36 | -------------------------------------------------------------------------------- /protobuf-test/src/common/v2/test_serde_derive_pb.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto2"; 2 | 3 | import "rustproto.proto"; 4 | option (rustproto.generate_accessors_all) = true; 5 | 6 | option (rustproto.serde_derive_all) = true; 7 | 8 | 9 | 10 | enum AnEnum { 11 | TEST = 0; 12 | } 13 | 14 | message OneOf { 15 | oneof food { 16 | uint32 rice = 1; 17 | uint32 pasta = 2; 18 | } 19 | } 20 | 21 | message SomeMessage { 22 | } 23 | 24 | message TestSingularPtrField { 25 | optional SomeMessage test = 1; 26 | } 27 | 28 | message TestSingularInt { 29 | optional uint32 iii = 3; 30 | } 31 | 32 | message RepeatedInt { 33 | repeated uint32 test_repeated = 1; 34 | } 35 | 36 | message MessageInRepeatedMessage { 37 | optional uint32 x = 1; 38 | } 39 | 40 | message RepeatedMessage { 41 | repeated MessageInRepeatedMessage test_repeated = 1; 42 | } 43 | 44 | message TestSerdeMap { 45 | map test_map = 1; 46 | } 47 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: false 2 | 3 | language: rust 4 | 5 | cache: 6 | directories: 7 | - $HOME/.ccache 8 | 9 | matrix: 10 | include: 11 | - name: Stable 12 | rust: stable 13 | env: PROTOBUF_VERSION=3.6.1 14 | - name: Beta 15 | rust: beta 16 | env: PROTOBUF_VERSION=3.6.1 17 | - name: Stable bytes 18 | rust: stable 19 | env: PROTOBUF_VERSION=3.6.1 RUST_PROTOBUF_FEATURES=with-bytes 20 | - name: Stable serde 21 | rust: stable 22 | env: PROTOBUF_VERSION=3.6.1 RUST_PROTOBUF_FEATURES=with-serde 23 | - name: Nightly all features 24 | rust: nightly 25 | env: PROTOBUF_VERSION=3.6.1 RUST_PROTOBUF_FEATURES=with-serde,with-bytes 26 | - name: Windows 27 | os: windows 28 | rust: stable 29 | env: PROTOBUF_VERSION=3.6.1 ON_WINDOWS=1 30 | # allow_failures: 31 | # - os: windows 32 | 33 | script: 34 | - ci/run.sh 35 | 36 | notifications: 37 | email: 38 | on_success: never 39 | 40 | # vim: set ts=2 sw=2 et: 41 | -------------------------------------------------------------------------------- /protobuf/src/misc.rs: -------------------------------------------------------------------------------- 1 | use std::mem; 2 | 3 | /// Slice from `vec[vec.len()..vec.capacity()]` 4 | pub unsafe fn remaining_capacity_as_slice_mut(vec: &mut Vec) -> &mut [A] { 5 | let range = vec.len()..vec.capacity(); 6 | vec.get_unchecked_mut(range) 7 | } 8 | 9 | pub unsafe fn remove_lifetime_mut(a: &mut A) -> &'static mut A { 10 | mem::transmute(a) 11 | } 12 | 13 | #[cfg(test)] 14 | mod test { 15 | use super::*; 16 | 17 | #[test] 18 | fn test_remaining_capacity_as_slice_mut() { 19 | let mut v = Vec::with_capacity(5); 20 | v.push(10); 21 | v.push(11); 22 | v.push(12); 23 | unsafe { 24 | { 25 | let s = remaining_capacity_as_slice_mut(&mut v); 26 | assert_eq!(2, s.len()); 27 | s[0] = 13; 28 | s[1] = 14; 29 | } 30 | v.set_len(5); 31 | } 32 | assert_eq!(vec![10, 11, 12, 13, 14], v); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /protoc/test-protoc/build.rs: -------------------------------------------------------------------------------- 1 | extern crate protoc; 2 | 3 | use std::ffi::OsString; 4 | use std::io::Result; 5 | use std::path::PathBuf; 6 | 7 | fn main() -> Result<()> { 8 | let exe_suffix = if cfg!(windows) { 9 | ".exe" 10 | } else if cfg!(unix) { 11 | "" 12 | } else { 13 | panic!("unknown OS") 14 | }; 15 | 16 | // TODO: https://github.com/rust-lang/cargo/issues/4316 17 | 18 | let gen_rust_binary = format!("../../target/debug/protoc-gen-rust{}", exe_suffix); 19 | let gen_rust_binary = PathBuf::from(gen_rust_binary).canonicalize()?; 20 | 21 | assert!(gen_rust_binary.is_file(), "{:?}", gen_rust_binary); 22 | 23 | let mut gen_rust_plugin = OsString::from("protoc-gen-rust="); 24 | gen_rust_plugin.push(gen_rust_binary); 25 | 26 | protoc::Args::new() 27 | .lang("rust") 28 | .out_dir("src") 29 | .plugin(gen_rust_plugin) 30 | .input("src/data.proto") 31 | .run()?; 32 | 33 | Ok(()) 34 | } 35 | -------------------------------------------------------------------------------- /protobuf-codegen-pure/src/test_against_protobuf_protos.rs: -------------------------------------------------------------------------------- 1 | use std::fs; 2 | use std::io::Read; 3 | use std::path::Path; 4 | 5 | use crate::model; 6 | 7 | fn parse_recursively(path: &Path) { 8 | let file_name = path 9 | .file_name() 10 | .expect("file_name") 11 | .to_str() 12 | .expect("to_str"); 13 | if path.is_dir() { 14 | for entry in fs::read_dir(path).expect("read_dir") { 15 | parse_recursively(&entry.expect("entry").path()); 16 | } 17 | } else if file_name.ends_with(".proto") { 18 | println!("checking {}", path.display()); 19 | let mut content = String::new(); 20 | fs::File::open(path) 21 | .expect("open") 22 | .read_to_string(&mut content) 23 | .expect("read"); 24 | model::FileDescriptor::parse(&content).expect("parse"); 25 | } 26 | } 27 | 28 | #[test] 29 | fn test() { 30 | let path = &Path::new("../google-protobuf"); 31 | parse_recursively(&Path::new(path)); 32 | } 33 | -------------------------------------------------------------------------------- /protobuf/src/reflect/rt.rs: -------------------------------------------------------------------------------- 1 | //! This module contains functions references for reflection in generated code. 2 | //! Should not probably be used directly. 3 | 4 | pub use crate::reflect::accessor::map::make_map_accessor; 5 | pub use crate::reflect::accessor::repeated::make_repeated_field_accessor; 6 | pub use crate::reflect::accessor::repeated::make_vec_accessor; 7 | pub use crate::reflect::accessor::singular::make_option_accessor; 8 | pub use crate::reflect::accessor::singular::make_option_get_copy_accessor; 9 | pub use crate::reflect::accessor::singular::make_option_get_ref_accessor; 10 | pub use crate::reflect::accessor::singular::make_simple_field_accessor; 11 | pub use crate::reflect::accessor::singular::make_oneof_copy_has_get_set_accessors; 12 | pub use crate::reflect::accessor::singular::make_oneof_deref_has_get_set_accessor; 13 | pub use crate::reflect::accessor::singular::make_oneof_message_has_get_mut_set_accessor; 14 | pub use crate::reflect::accessor::singular::make_option_enum_accessor; 15 | pub use crate::reflect::accessor::FieldAccessor; 16 | -------------------------------------------------------------------------------- /protobuf-codegen/src/bin/protobuf-bin-gen-rust-do-not-use.rs: -------------------------------------------------------------------------------- 1 | extern crate protobuf; 2 | extern crate protobuf_codegen; 3 | 4 | use std::fs::*; 5 | use std::io::Read; 6 | use std::path::{Path, PathBuf}; 7 | 8 | use protobuf::descriptor::*; 9 | use protobuf::parse_from_reader; 10 | use protobuf_codegen::*; 11 | 12 | fn write_file(bin: &str) { 13 | let mut is = File::open(&Path::new(bin)).unwrap(); 14 | let fds = parse_from_reader::(&mut is as &mut Read).unwrap(); 15 | 16 | let file_names: Vec = fds.file.iter().map(|f| f.get_name().into()).collect(); 17 | gen_and_write( 18 | &fds.file, 19 | &format!("unknown, file {}", bin), 20 | &file_names, 21 | Path::new("."), 22 | &Default::default(), 23 | ) 24 | .expect("gen_and_write"); 25 | } 26 | 27 | fn main() { 28 | let args: Vec = std::env::args().collect(); 29 | if args.len() != 2 { 30 | panic!("must have exactly one argument"); 31 | } 32 | let ref pb_bin = args[1]; 33 | write_file(&pb_bin); 34 | } 35 | -------------------------------------------------------------------------------- /protobuf/src/reflect/type_dynamic.rs: -------------------------------------------------------------------------------- 1 | //! Reflection internals. 2 | 3 | use std::marker; 4 | 5 | use crate::reflect::runtime_type_dynamic::RuntimeTypeDynamic; 6 | use crate::reflect::runtime_types::RuntimeType; 7 | use crate::reflect::types::ProtobufType; 8 | use crate::wire_format::WireType; 9 | 10 | /// Dynamic version of [`ProtobufType`](crate::reflect::types::ProtobufType). 11 | /// 12 | /// This is used internally. 13 | pub trait ProtobufTypeDynamic: Send + Sync + 'static { 14 | /// Wire type for this type. 15 | fn wire_type(&self) -> WireType; 16 | 17 | /// Get runtime type for this protobuf type. 18 | fn runtime_type(&self) -> &dyn RuntimeTypeDynamic; 19 | } 20 | 21 | pub(crate) struct ProtobufTypeDynamicImpl(pub marker::PhantomData); 22 | 23 | impl ProtobufTypeDynamic for ProtobufTypeDynamicImpl { 24 | fn wire_type(&self) -> WireType { 25 | T::WIRE_TYPE 26 | } 27 | 28 | fn runtime_type(&self) -> &dyn RuntimeTypeDynamic { 29 | ::dynamic() 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /protobuf/src/text_format/mod.rs: -------------------------------------------------------------------------------- 1 | //! Protobuf "text format" implementation. 2 | //! 3 | //! Text format message look like this: 4 | //! 5 | //! ```text,ignore 6 | //! size: 17 7 | //! color: "red" 8 | //! children { 9 | //! size: 18 10 | //! color: "blue" 11 | //! } 12 | //! children { 13 | //! size: 19 14 | //! color: "green" 15 | //! } 16 | //! ``` 17 | //! 18 | //! This format is not specified, but it is implemented by all official 19 | //! protobuf implementations, including `protoc` command which can decode 20 | //! and encode messages using text format. 21 | 22 | mod parse; 23 | mod print; 24 | 25 | // Used by text format parser and by pure-rust codegen parsed 26 | // this it is public but hidden module. 27 | // https://github.com/rust-lang/rust/issues/44663 28 | #[doc(hidden)] 29 | pub mod lexer; 30 | 31 | pub use self::print::fmt; 32 | pub use self::print::print_to; 33 | pub use self::print::print_to_string; 34 | #[doc(hidden)] 35 | pub use self::print::quote_escape_bytes; 36 | 37 | pub use self::parse::merge_from_str; 38 | pub use self::parse::parse_from_str; 39 | -------------------------------------------------------------------------------- /protobuf-test/src/common/v2/test_oneof_pb.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto2"; 2 | 3 | import "rustproto.proto"; 4 | option (rustproto.generate_accessors_all) = true; 5 | 6 | 7 | package test_oneof; 8 | 9 | enum EnumForOneof { 10 | UNKNOWN = 0; 11 | A = 10; 12 | } 13 | 14 | message MessageForOneof { 15 | optional int32 f = 1; 16 | } 17 | 18 | message TestOneof { 19 | optional string s = 29; 20 | oneof one { 21 | double double_field = 1; 22 | float float_field = 2; 23 | int32 int32_field = 3; 24 | int64 int64_field = 4; 25 | uint32 uint32_field = 5; 26 | uint64 uint64_field = 6; 27 | sint32 sint32_field = 7; 28 | sint64 sint64_field = 8; 29 | fixed32 fixed32_field = 9; 30 | fixed64 fixed64_field = 10; 31 | sfixed32 sfixed32_field = 11; 32 | sfixed64 sfixed64_field = 12; 33 | bool bool_field = 13; 34 | string string_field = 14; 35 | bytes bytes_field = 15; 36 | EnumForOneof enum_field = 16; 37 | MessageForOneof message_field = 17; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /protobuf-test/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "protobuf-test" 3 | version = "0.0.0" 4 | authors = ["Stepan Koltsov "] 5 | publish = false 6 | edition = "2018" 7 | 8 | [lib] 9 | doctest = false 10 | bench = false 11 | 12 | [features] 13 | default = [] 14 | proto3 = [] 15 | with-bytes = ["bytes", "protobuf/with-bytes", "protobuf-test-common/with-bytes"] 16 | with-serde = ["serde", "serde_derive", "serde_json", "protobuf/with-serde", "protobuf-test-common/with-serde"] 17 | 18 | [build-dependencies] 19 | protoc = { path = "../protoc" } 20 | protoc-rust = { path = "../protoc-rust" } 21 | protobuf-test-common = { path = "../protobuf-test-common" } 22 | glob = "0.2" 23 | log = "0.*" 24 | env_logger = "0.5.*" 25 | 26 | [dependencies] 27 | protobuf-test-common = { path = "../protobuf-test-common" } 28 | serde = { version = "1.0", optional = true } 29 | serde_derive = { version = "1.0", optional = true } 30 | serde_json = { version = "1.0", optional = true } 31 | bytes = { version = "0.4", optional = true } 32 | 33 | [dependencies.protobuf] 34 | path = "../protobuf" 35 | -------------------------------------------------------------------------------- /protobuf-codegen-pure-test/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "protobuf-codegen-pure-test" 3 | version = "0.0.0" 4 | authors = ["Stepan Koltsov "] 5 | publish = false 6 | edition = "2018" 7 | 8 | [lib] 9 | doctest = false 10 | bench = false 11 | 12 | [features] 13 | default = [] 14 | proto3 = [] 15 | with-bytes = ["bytes", "protobuf/with-bytes", "protobuf-test-common/with-bytes"] 16 | with-serde = ["serde", "serde_derive", "serde_json", "protobuf/with-serde", "protobuf-test-common/with-serde"] 17 | 18 | [build-dependencies] 19 | protobuf-codegen-pure = { path = "../protobuf-codegen-pure" } 20 | protobuf-test-common = { path = "../protobuf-test-common" } 21 | glob = "0.2" 22 | log = "0.*" 23 | env_logger = "0.5.*" 24 | 25 | [dependencies] 26 | protobuf-test-common = { path = "../protobuf-test-common" } 27 | serde = { version = "1.0", optional = true } 28 | serde_derive = { version = "1.0", optional = true } 29 | serde_json = { version = "1.0", optional = true } 30 | bytes = { version = "0.4", optional = true } 31 | 32 | [dependencies.protobuf] 33 | path = "../protobuf" 34 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2019 Stepan Koltsov 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 14 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 15 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 16 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 17 | DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 18 | OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE 19 | OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /protobuf-test/README.md: -------------------------------------------------------------------------------- 1 | # Tests for rust-protobuf 2 | 3 | To execute tests simply execute `cargo test`. 4 | 5 | If protobuf 3 is installed, command will include test for protobuf 3 generated code. 6 | 7 | If `--features=with-bytes` flag is specified, tests will include test for `with-bytes` feature, 8 | which is not enabled by default. 9 | 10 | `./test.sh` is to be used from [travis-ci](https://travis-ci.org/stepancheg/rust-protobuf/), 11 | and not needed for local development. 12 | 13 | `cargo test` executes [`build.rs`](https://github.com/stepancheg/rust-protobuf/blob/master/protobuf-test/build.rs) script, 14 | which generates `.rs` files from `.proto` and `mod.rs` files for certain folder. 15 | 16 | ## Test contents 17 | 18 | * `v2` contains tests specific to protobuf 2 19 | * `v3` contains tests specific to protobuf 2 20 | * `google` contains tests `.proto` files taken from Google's protobuf implementation 21 | * `common` contains tests which are identical for both versions of protobuf syntax. 22 | `common/v2` directory contains sources, and contents of `common/v3` is generated 23 | from `common/v2` by copy and replace. 24 | -------------------------------------------------------------------------------- /protobuf/LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2019 Stepan Koltsov 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 14 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 15 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 16 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 17 | DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 18 | OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE 19 | OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /protoc/LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2019 Stepan Koltsov 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 14 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 15 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 16 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 17 | DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 18 | OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE 19 | OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /protoc-rust/LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2019 Stepan Koltsov 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 14 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 15 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 16 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 17 | DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 18 | OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE 19 | OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /protobuf-codegen/LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2019 Stepan Koltsov 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 14 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 15 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 16 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 17 | DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 18 | OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE 19 | OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /protobuf/src/reflect/mod.rs: -------------------------------------------------------------------------------- 1 | //! Reflection implementation for protobuf types. 2 | 3 | mod accessor; 4 | mod enums; 5 | mod field; 6 | mod map; 7 | mod message; 8 | mod repeated; 9 | mod runtime_type_box; 10 | mod runtime_type_dynamic; 11 | pub(crate) mod runtime_types; 12 | mod transmute_eq; 13 | mod type_dynamic; 14 | pub mod types; 15 | mod value; 16 | mod find_message_or_enum; 17 | 18 | mod reflect_deep_eq; 19 | 20 | pub mod rt; 21 | 22 | pub use self::value::ProtobufValue; 23 | pub use self::value::ReflectValueBox; 24 | pub use self::value::ReflectValueRef; 25 | 26 | pub use self::repeated::ReflectRepeatedMut; 27 | pub use self::repeated::ReflectRepeatedRef; 28 | 29 | pub use self::map::ReflectMapMut; 30 | pub use self::map::ReflectMapRef; 31 | 32 | pub use self::enums::EnumDescriptor; 33 | pub use self::enums::EnumValueDescriptor; 34 | 35 | pub use self::message::MessageDescriptor; 36 | 37 | pub use self::field::FieldDescriptor; 38 | pub use self::field::ReflectFieldRef; 39 | pub use self::field::RuntimeFieldType; 40 | 41 | pub use self::runtime_type_box::RuntimeTypeBox; 42 | pub use self::runtime_type_dynamic::RuntimeTypeDynamic; 43 | -------------------------------------------------------------------------------- /protobuf-codegen-pure/LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2019 Stepan Koltsov 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 14 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 15 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 16 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 17 | DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 18 | OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE 19 | OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /protobuf-test/src/common/v2/test_singular_field_option_pb.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto2"; 2 | 3 | import "rustproto.proto"; 4 | 5 | package test_singular_field_option; 6 | 7 | message Inner { 8 | optional int32 size = 1; 9 | } 10 | 11 | message WithOptionBox { 12 | option (rustproto.singular_field_option_box) = true; 13 | option (rustproto.singular_field_option) = false; 14 | option (rustproto.expose_fields) = true; 15 | 16 | optional Inner inner = 1; 17 | optional string s = 2; 18 | optional bytes b = 3; 19 | } 20 | 21 | message WithOption { 22 | option (rustproto.singular_field_option_box) = false; 23 | option (rustproto.singular_field_option) = true; 24 | option (rustproto.expose_fields) = true; 25 | 26 | optional Inner inner = 1; 27 | optional string s = 2; 28 | optional bytes b = 3; 29 | } 30 | 31 | message WithSingularField { 32 | option (rustproto.singular_field_option_box) = false; 33 | option (rustproto.singular_field_option) = false; 34 | option (rustproto.expose_fields) = true; 35 | 36 | optional Inner inner = 1; 37 | optional string s = 2; 38 | optional bytes b = 3; 39 | } 40 | -------------------------------------------------------------------------------- /protobuf-test/src/common/v2/test_sync.rs: -------------------------------------------------------------------------------- 1 | use std::sync::Arc; 2 | use std::thread; 3 | 4 | use protobuf::CodedInputStream; 5 | use protobuf::Message; 6 | 7 | use super::test_sync_pb::*; 8 | 9 | // test messages are sync 10 | #[test] 11 | fn test_sync() { 12 | let m = Arc::new({ 13 | let mut r = TestSync::new(); 14 | r.set_int32_field(23); 15 | r 16 | }); 17 | 18 | let threads: Vec<_> = (0..4) 19 | .map(|_| { 20 | let m_copy = m.clone(); 21 | thread::spawn(move || { 22 | let bytes = m_copy.write_to_bytes().unwrap(); 23 | let mut is = CodedInputStream::from_bytes(&bytes); 24 | let mut read = TestSync::new(); 25 | // API is not very convenient here 26 | read.merge_from(&mut is).unwrap(); 27 | read.check_initialized().unwrap(); 28 | read.get_int32_field() 29 | }) 30 | }).collect(); 31 | 32 | let results = threads 33 | .into_iter() 34 | .map(|t| t.join().unwrap()) 35 | .collect::>(); 36 | assert_eq!(&[23, 23, 23, 23], &results[..]); 37 | } 38 | -------------------------------------------------------------------------------- /protobuf-fuzz/fuzz/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "protobuf-fuzz-fuzz" 3 | version = "0.0.1" 4 | authors = ["Automatically generated"] 5 | publish = false 6 | edition = "2018" 7 | 8 | [package.metadata] 9 | cargo-fuzz = true 10 | 11 | [dependencies.protobuf-fuzz] 12 | path = ".." 13 | [dependencies.libfuzzer-sys] 14 | git = "https://github.com/rust-fuzz/libfuzzer-sys.git" 15 | 16 | # Prevent this from interfering with workspaces 17 | [workspace] 18 | members = ["."] 19 | 20 | [[bin]] 21 | name = "all" 22 | path = "fuzz_targets/all.rs" 23 | 24 | [[bin]] 25 | name = "empty_message" 26 | path = "fuzz_targets/empty_message.rs" 27 | 28 | [[bin]] 29 | name = "empty_message_read" 30 | path = "fuzz_targets/empty_message_read.rs" 31 | 32 | [[bin]] 33 | name = "singular" 34 | path = "fuzz_targets/singular.rs" 35 | 36 | [[bin]] 37 | name = "singular_read" 38 | path = "fuzz_targets/singular_read.rs" 39 | 40 | [[bin]] 41 | name = "repeated" 42 | path = "fuzz_targets/repeated.rs" 43 | 44 | [[bin]] 45 | name = "repeated_read" 46 | path = "fuzz_targets/repeated_read.rs" 47 | 48 | [[bin]] 49 | name = "map" 50 | path = "fuzz_targets/map.rs" 51 | 52 | [[bin]] 53 | name = "map_read" 54 | path = "fuzz_targets/map_read.rs" 55 | -------------------------------------------------------------------------------- /protobuf-test/src/common/v2/test_map_carllerche.rs: -------------------------------------------------------------------------------- 1 | use bytes::Bytes; 2 | 3 | use protobuf::*; 4 | 5 | use protobuf_test_common::*; 6 | 7 | use super::test_map_carllerche_pb::*; 8 | 9 | #[test] 10 | fn test_string_to_int32() { 11 | let mut map = TestMapCarllerche::new(); 12 | map.string_to_int32.insert(Chars::from("abc"), 17); 13 | test_serialize_deserialize("0a 07 0a 03 61 62 63 10 11", &map); 14 | // field 1, length-delimited 15 | // length 16 | // field 1, wire type 2 17 | // length 18 | // a b c 19 | // field 2, varint 20 | // 17 21 | } 22 | 23 | #[test] 24 | fn test_int32_to_bytes() { 25 | let mut map = TestMapCarllerche::new(); 26 | map.int32_to_string.insert(17, Chars::from("abc")); 27 | test_serialize_deserialize("12 07 08 11 12 03 61 62 63", &map); 28 | let mut map = TestMapCarllerche::new(); 29 | map.int32_to_bytes.insert(17, Bytes::from("abc")); 30 | test_serialize_deserialize("1a 07 08 11 12 03 61 62 63", &map); 31 | } 32 | -------------------------------------------------------------------------------- /protobuf/src/cached_size.rs: -------------------------------------------------------------------------------- 1 | use std::hash::Hash; 2 | use std::hash::Hasher; 3 | use std::sync::atomic::AtomicUsize; 4 | use std::sync::atomic::Ordering; 5 | 6 | /// Cached size field used in generated code. 7 | /// 8 | /// It is always equal to itself to simplify generated code. 9 | /// (Generated code can use `#[derive(Eq)]`). 10 | /// 11 | /// This type should rarely be used directly. 12 | #[derive(Debug, Default)] 13 | pub struct CachedSize { 14 | size: AtomicUsize, 15 | } 16 | 17 | impl CachedSize { 18 | /// Get cached size 19 | pub fn get(&self) -> u32 { 20 | self.size.load(Ordering::Relaxed) as u32 21 | } 22 | 23 | /// Set cached size 24 | pub fn set(&self, size: u32) { 25 | self.size.store(size as usize, Ordering::Relaxed) 26 | } 27 | } 28 | 29 | impl Clone for CachedSize { 30 | fn clone(&self) -> CachedSize { 31 | CachedSize { 32 | size: AtomicUsize::new(self.size.load(Ordering::Relaxed)), 33 | } 34 | } 35 | } 36 | 37 | impl PartialEq for CachedSize { 38 | fn eq(&self, _other: &CachedSize) -> bool { 39 | true 40 | } 41 | } 42 | 43 | impl Eq for CachedSize {} 44 | 45 | impl Hash for CachedSize { 46 | fn hash(&self, _state: &mut H) { 47 | // ignore cached size in cache computation 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /protobuf-codegen-pure/README.md: -------------------------------------------------------------------------------- 1 | # API to generate .rs files 2 | 3 | API to generate `.rs` files to be used e. g. [from build.rs](https://github.com/stepancheg/rust-protobuf/blob/master/protobuf-codegen-pure-test/build.rs). 4 | 5 | Example code: 6 | 7 | With stable rust-protobuf: 8 | 9 | ```rust 10 | extern crate protobuf_codegen_pure; 11 | 12 | protobuf_codegen_pure::run(protobuf_codegen_pure::Args { 13 | out_dir: "src/protos", 14 | input: &["protos/a.proto", "protos/b.proto"], 15 | includes: &["protos"], 16 | customize: protobuf_codegen_pure::Customize { 17 | ..Default::default() 18 | }, 19 | }).expect("protoc"); 20 | ``` 21 | 22 | With rust-protobuf from master: 23 | 24 | ```rust 25 | extern crate protobuf_codegen_pure; 26 | 27 | protobuf_codegen_pure::Args::new() 28 | .out_dir("src/protos") 29 | .inputs(&["protos/a.proto", "protos/b.proto"]) 30 | .include("protos") 31 | .run() 32 | .expect("protoc"); 33 | ``` 34 | 35 | And in `Cargo.toml`: 36 | 37 | ``` 38 | [build-dependencies] 39 | protobuf-codegen-pure = "2.3" 40 | ``` 41 | 42 | The alternative is to use 43 | [protoc-rust crate](https://github.com/stepancheg/rust-protobuf/tree/master/protoc-rust), 44 | which relies on `protoc` command to parse descriptors. Both crates should produce the same result, 45 | otherwise please file a bug report. 46 | -------------------------------------------------------------------------------- /ci/install-protobuf.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -ex 4 | 5 | die() { 6 | echo "$@" >&2 7 | exit 1 8 | } 9 | 10 | test -n "$PROTOBUF_VERSION" || die "PROTOBUF_VERSION env var is undefined" 11 | 12 | case `uname` in 13 | Linux) 14 | # Check we have ccache 15 | ccache --version 16 | export CC="ccache gcc" 17 | export CXX="ccache g++" 18 | 19 | case "$PROTOBUF_VERSION" in 20 | 2*) 21 | basename=protobuf-$PROTOBUF_VERSION 22 | ;; 23 | 3*) 24 | basename=protobuf-cpp-$PROTOBUF_VERSION 25 | ;; 26 | *) 27 | die "unknown protobuf version: $PROTOBUF_VERSION" 28 | ;; 29 | esac 30 | 31 | curl -sL https://github.com/protocolbuffers/protobuf/releases/download/v$PROTOBUF_VERSION/$basename.tar.gz | tar zx 32 | 33 | cd protobuf-$PROTOBUF_VERSION 34 | 35 | ./configure --prefix=$HOME && make -j2 && make install 36 | 37 | ;; 38 | MSYS_NT*) 39 | ( 40 | cd $HOME 41 | curl -sLO https://github.com/protocolbuffers/protobuf/releases/download/v$PROTOBUF_VERSION/protoc-$PROTOBUF_VERSION-win32.zip 42 | unzip protoc-$PROTOBUF_VERSION-win32.zip 43 | ) 44 | ;; 45 | *) 46 | die "unknown uname: `uname`" 47 | ;; 48 | esac 49 | 50 | $HOME/bin/protoc --version 51 | -------------------------------------------------------------------------------- /protobuf-test/src/v2/test_oneof_default_value_pb.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto2"; 2 | 3 | package test_oneof_default_value_pb; 4 | 5 | enum EnumForOneofDefaultValue { 6 | A = 10; 7 | B = 20; 8 | } 9 | 10 | message MessageForOneofDefaultValue { 11 | optional int32 f = 1; 12 | } 13 | 14 | message TestOneofDefaultValue { 15 | optional string s = 29; 16 | oneof one { 17 | double double_field = 1 [default = 9.0]; 18 | float float_field = 2 [default = 10.0]; 19 | int32 int32_field = 3 [default = 11]; 20 | int64 int64_field = 4 [default = 12]; 21 | uint32 uint32_field = 5 [default = 13]; 22 | uint64 uint64_field = 6 [default = 14]; 23 | sint32 sint32_field = 7 [default = 15]; 24 | sint64 sint64_field = 8 [default = 16]; 25 | fixed32 fixed32_field = 9 [default = 17]; 26 | fixed64 fixed64_field = 10 [default = 18]; 27 | sfixed32 sfixed32_field = 11 [default = 19]; 28 | sfixed64 sfixed64_field = 12 [default = 20]; 29 | bool bool_field = 13 [default = true]; 30 | string string_field = 14 [default = "ss"]; 31 | bytes bytes_field = 15 [default = "bb"]; 32 | EnumForOneofDefaultValue enum_field = 16 [default = B]; 33 | MessageForOneofDefaultValue message_field = 17; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /perftest/vs-cxx/perftest_data.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto2"; 2 | 3 | message Test1 { 4 | optional int32 value = 1; 5 | } 6 | 7 | message TestRepeatedBool { 8 | repeated bool values = 1; 9 | } 10 | 11 | message TestRepeatedPackedInt32 { 12 | repeated int32 values = 1 [ packed = true ]; 13 | } 14 | 15 | message TestRepeatedMessages { 16 | repeated TestRepeatedMessages messages1 = 1; 17 | repeated TestRepeatedMessages messages2 = 2; 18 | repeated TestRepeatedMessages messages3 = 3; 19 | } 20 | 21 | message TestOptionalMessages { 22 | optional TestOptionalMessages message1 = 1; 23 | optional TestOptionalMessages message2 = 2; 24 | optional TestOptionalMessages message3 = 3; 25 | } 26 | 27 | message TestStrings { 28 | optional string s1 = 1; 29 | optional string s2 = 2; 30 | optional string s3 = 3; 31 | } 32 | 33 | message TestBytes { 34 | optional bytes b1 = 1; 35 | } 36 | 37 | message PerftestData { 38 | repeated Test1 test1 = 1; 39 | repeated TestRepeatedBool test_repeated_bool = 2; 40 | repeated TestRepeatedMessages test_repeated_messages = 3; 41 | repeated TestOptionalMessages test_optional_messages = 4; 42 | repeated TestStrings test_strings = 5; 43 | repeated TestRepeatedPackedInt32 test_repeated_packed_int32 = 6; 44 | repeated TestBytes test_small_bytearrays = 7; 45 | repeated TestBytes test_large_bytearrays = 8; 46 | } 47 | -------------------------------------------------------------------------------- /protobuf/src/text_format/lexer/str_lit.rs: -------------------------------------------------------------------------------- 1 | use super::lexer_impl::Lexer; 2 | use super::lexer_impl::LexerError; 3 | use crate::text_format::lexer::ParserLanguage; 4 | 5 | #[derive(Debug)] 6 | pub enum StrLitDecodeError { 7 | Error, 8 | } 9 | 10 | impl From for StrLitDecodeError { 11 | fn from(_: LexerError) -> Self { 12 | StrLitDecodeError::Error 13 | } 14 | } 15 | 16 | pub type StrLitDecodeResult = Result; 17 | 18 | /// String literal, both `string` and `bytes`. 19 | #[derive(Clone, Eq, PartialEq, Debug)] 20 | pub struct StrLit { 21 | pub escaped: String, 22 | } 23 | 24 | impl StrLit { 25 | /// May fail if not valid UTF8 26 | pub fn decode_utf8(&self) -> StrLitDecodeResult { 27 | let mut lexer = Lexer::new(&self.escaped, ParserLanguage::Json); 28 | let mut r = String::new(); 29 | while !lexer.eof() { 30 | r.push(lexer.next_char_value()?); 31 | } 32 | Ok(r) 33 | } 34 | 35 | pub fn decode_bytes(&self) -> StrLitDecodeResult> { 36 | let mut lexer = Lexer::new(&self.escaped, ParserLanguage::Json); 37 | let mut r = Vec::new(); 38 | while !lexer.eof() { 39 | r.push(lexer.next_byte_value()?); 40 | } 41 | Ok(r) 42 | } 43 | 44 | pub fn quoted(&self) -> String { 45 | format!("\"{}\"", self.escaped) 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /protobuf-test-common/src/json_tests.rs: -------------------------------------------------------------------------------- 1 | use protobuf::json; 2 | use protobuf::text_format; 3 | use protobuf::Message; 4 | 5 | pub fn test_json_print_parse_message(s: &str, m: &Message) { 6 | assert_eq!(s, json::print_to_string(m).expect("print_to_string")); 7 | 8 | test_json_parse_message(s, m); 9 | } 10 | 11 | pub fn test_json_parse_message(s: &str, m: &Message) { 12 | let descriptor = m.descriptor(); 13 | 14 | let mut new = descriptor.new_instance(); 15 | json::merge_from_str(&mut *new, s).expect("parse"); 16 | assert!( 17 | descriptor.deep_eq(m, &*new), 18 | "{:?} should be == {:?}", 19 | text_format::print_to_string(m), 20 | text_format::print_to_string(&*new) 21 | ); 22 | } 23 | 24 | /// Print message to string, parse the string, 25 | /// then check resulting message is equal to the original. 26 | pub fn test_json_message(m: &Message) { 27 | let descriptor = m.descriptor(); 28 | 29 | let s = json::print_to_string(m).expect("print_to_string"); 30 | let mut new = descriptor.new_instance(); 31 | json::merge_from_str(&mut *new, &s).expect(&format!( 32 | "failed to parse serialized: {}; from message: {:?}", 33 | s, m 34 | )); 35 | assert!( 36 | descriptor.deep_eq(m, &*new), 37 | "{:?} should be == {:?}", 38 | text_format::print_to_string(m), 39 | text_format::print_to_string(&*new) 40 | ); 41 | } 42 | -------------------------------------------------------------------------------- /protobuf/src/text_format/lexer/token.rs: -------------------------------------------------------------------------------- 1 | use super::lexer_impl::LexerError; 2 | use super::lexer_impl::LexerResult; 3 | use super::loc::Loc; 4 | use super::num_lit::NumLit; 5 | use super::str_lit::StrLit; 6 | use crate::text_format::lexer::JsonNumberLit; 7 | 8 | #[derive(Clone, Debug, PartialEq)] 9 | pub enum Token { 10 | Ident(String), 11 | Symbol(char), 12 | // Protobuf tokenizer has separate tokens for int and float. 13 | // Tokens do not include sign. 14 | IntLit(u64), 15 | FloatLit(f64), 16 | JsonNumber(JsonNumberLit), 17 | // including quotes 18 | StrLit(StrLit), 19 | } 20 | 21 | impl Token { 22 | /// Back to original 23 | pub fn format(&self) -> String { 24 | match self { 25 | &Token::Ident(ref s) => s.clone(), 26 | &Token::Symbol(c) => c.to_string(), 27 | &Token::IntLit(ref i) => i.to_string(), 28 | &Token::StrLit(ref s) => s.quoted(), 29 | &Token::FloatLit(ref f) => f.to_string(), 30 | &Token::JsonNumber(ref f) => f.to_string(), 31 | } 32 | } 33 | 34 | pub fn to_num_lit(&self) -> LexerResult { 35 | match self { 36 | &Token::IntLit(i) => Ok(NumLit::U64(i)), 37 | &Token::FloatLit(f) => Ok(NumLit::F64(f)), 38 | _ => Err(LexerError::IncorrectInput), 39 | } 40 | } 41 | } 42 | 43 | #[derive(Clone)] 44 | pub struct TokenWithLocation { 45 | pub token: Token, 46 | pub loc: Loc, 47 | } 48 | -------------------------------------------------------------------------------- /protobuf-codegen/src/compiler_plugin.rs: -------------------------------------------------------------------------------- 1 | use protobuf::descriptor::FileDescriptorProto; 2 | use protobuf::parse_from_reader; 3 | use protobuf::plugin::*; 4 | use protobuf::Message; 5 | use std::io::stdin; 6 | use std::io::stdout; 7 | use std::path::PathBuf; 8 | use std::str; 9 | 10 | pub struct GenRequest<'a> { 11 | pub file_descriptors: &'a [FileDescriptorProto], 12 | pub files_to_generate: &'a [PathBuf], 13 | pub parameter: &'a str, 14 | } 15 | 16 | pub struct GenResult { 17 | pub name: String, 18 | pub content: Vec, 19 | } 20 | 21 | pub fn plugin_main(gen: F) 22 | where 23 | F: Fn(&GenRequest) -> Vec, 24 | { 25 | let req = parse_from_reader::(&mut stdin()).unwrap(); 26 | let result = gen(&GenRequest { 27 | file_descriptors: &req.proto_file, 28 | files_to_generate: &req 29 | .file_to_generate 30 | .iter() 31 | .map(PathBuf::from) 32 | .collect::>(), 33 | parameter: req.get_parameter(), 34 | }); 35 | let mut resp = CodeGeneratorResponse::new(); 36 | resp.file = result 37 | .iter() 38 | .map(|file| { 39 | let mut r = code_generator_response::File::new(); 40 | r.set_name(file.name.to_string()); 41 | r.set_content(str::from_utf8(file.content.as_ref()).unwrap().to_string()); 42 | r 43 | }) 44 | .collect(); 45 | resp.write_to_writer(&mut stdout()).unwrap(); 46 | } 47 | -------------------------------------------------------------------------------- /protobuf-codegen/src/strx.rs: -------------------------------------------------------------------------------- 1 | pub fn remove_to<'s>(s: &'s str, c: char) -> &'s str { 2 | match s.rfind(c) { 3 | Some(pos) => &s[(pos + 1)..], 4 | None => s, 5 | } 6 | } 7 | 8 | pub fn remove_suffix<'s>(s: &'s str, suffix: &str) -> &'s str { 9 | if !s.ends_with(suffix) { 10 | s 11 | } else { 12 | &s[..(s.len() - suffix.len())] 13 | } 14 | } 15 | 16 | pub fn capitalize(s: &str) -> String { 17 | if s.is_empty() { 18 | return String::new(); 19 | } 20 | let mut char_indices = s.char_indices(); 21 | char_indices.next().unwrap(); 22 | match char_indices.next() { 23 | None => s.to_uppercase(), 24 | Some((i, _)) => s[..i].to_uppercase() + &s[i..], 25 | } 26 | } 27 | 28 | #[cfg(test)] 29 | mod test { 30 | 31 | use super::capitalize; 32 | use super::remove_suffix; 33 | use super::remove_to; 34 | 35 | #[test] 36 | fn test_remove_to() { 37 | assert_eq!("aaa", remove_to("aaa", '.')); 38 | assert_eq!("bbb", remove_to("aaa.bbb", '.')); 39 | assert_eq!("ccc", remove_to("aaa.bbb.ccc", '.')); 40 | } 41 | 42 | #[test] 43 | fn test_remove_suffix() { 44 | assert_eq!("bbb", remove_suffix("bbbaaa", "aaa")); 45 | assert_eq!("aaa", remove_suffix("aaa", "bbb")); 46 | } 47 | 48 | #[test] 49 | fn test_capitalize() { 50 | assert_eq!("", capitalize("")); 51 | assert_eq!("F", capitalize("f")); 52 | assert_eq!("Foo", capitalize("foo")); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /protoc-rust/README.md: -------------------------------------------------------------------------------- 1 | # API to generate .rs files 2 | 3 | API to generate `.rs` files to be used e. g. [from build.rs](https://github.com/stepancheg/rust-protobuf/blob/master/protobuf-test/build.rs). 4 | 5 | Example code: 6 | 7 | Using stable rust-protobuf: 8 | 9 | ```rust 10 | extern crate protoc_rust; 11 | 12 | use protoc_rust::Customize; 13 | 14 | fn main() { 15 | protoc_rust::run(protoc_rust::Args { 16 | out_dir: "src/protos", 17 | input: &["protos/a.proto", "protos/b.proto"], 18 | includes: &["protos"], 19 | customize: Customize { 20 | ..Default::default() 21 | }, 22 | }).expect("protoc"); 23 | } 24 | ``` 25 | 26 | Using rust-protobuf from master: 27 | 28 | ```rust 29 | extern crate protoc_rust; 30 | 31 | use protoc_rust::Customize; 32 | 33 | fn main() { 34 | protoc_rust::Args::new() 35 | .out_dir("src/protos") 36 | .inputs(&["protos/a.proto", "protos/b.proto"]), 37 | .include("protos") 38 | .run() 39 | .expect("protoc"); 40 | } 41 | ``` 42 | 43 | And in `Cargo.toml`: 44 | 45 | ``` 46 | [build-dependencies] 47 | protoc-rust = "2.0" 48 | ``` 49 | 50 | Note 1: This API requires `protoc` command present in `$PATH`. 51 | Although `protoc-gen-rust` command is not needed. 52 | 53 | Note 2: Is advisable that `protoc-rust` build-dependecy version be the same as `protobuf` dependency. 54 | 55 | The alternative is to use 56 | [pure-rust .proto parser and code generator](https://github.com/stepancheg/rust-protobuf/tree/master/protobuf-codegen-pure). 57 | -------------------------------------------------------------------------------- /perftest/bytes/build.rs: -------------------------------------------------------------------------------- 1 | extern crate protoc_rust; 2 | 3 | use std::env; 4 | use std::io::Read; 5 | use std::process; 6 | 7 | fn generate_protos() { 8 | protoc_rust::Args::new() 9 | .out_dir("src") 10 | .input("src/messages.proto") 11 | .includes(&["src", "../../proto"]) 12 | .run() 13 | .expect("protoc"); 14 | } 15 | 16 | // % rustc +stable --version 17 | // rustc 1.26.0 (a77568041 2018-05-07) 18 | // % rustc +beta --version 19 | // rustc 1.27.0-beta.1 (03fb2f447 2018-05-09) 20 | // % rustc +nightly --version 21 | // rustc 1.27.0-nightly (acd3871ba 2018-05-10) 22 | fn version_is_nightly(version: &str) -> bool { 23 | version.contains("nightly") 24 | } 25 | 26 | fn export_rustc_cfg() { 27 | let rustc = env::var("RUSTC").expect("RUSTC unset"); 28 | 29 | let mut child = process::Command::new(rustc) 30 | .args(&["--version"]) 31 | .stdin(process::Stdio::null()) 32 | .stdout(process::Stdio::piped()) 33 | .spawn() 34 | .expect("spawn rustc"); 35 | 36 | let mut rustc_version = String::new(); 37 | 38 | child 39 | .stdout 40 | .as_mut() 41 | .expect("stdout") 42 | .read_to_string(&mut rustc_version) 43 | .expect("read_to_string"); 44 | assert!(child.wait().expect("wait").success()); 45 | 46 | if version_is_nightly(&rustc_version) { 47 | println!("cargo:rustc-cfg=rustc_nightly"); 48 | } 49 | } 50 | 51 | fn main() { 52 | generate_protos(); 53 | 54 | export_rustc_cfg(); 55 | } 56 | -------------------------------------------------------------------------------- /protobuf-codegen/src/map.rs: -------------------------------------------------------------------------------- 1 | use protobuf::prelude::*; 2 | 3 | use crate::scope::FieldWithContext; 4 | use crate::scope::MessageWithScope; 5 | use protobuf::descriptor::field_descriptor_proto; 6 | 7 | /// Pair of (key, value) if this message is map entry 8 | pub(crate) fn map_entry<'a>( 9 | d: &'a MessageWithScope, 10 | ) -> Option<(FieldWithContext<'a>, FieldWithContext<'a>)> { 11 | if d.message.options.get_message().get_map_entry() { 12 | // Must be consistent with 13 | // DescriptorBuilder::ValidateMapEntry 14 | 15 | assert!(d.message.get_name().ends_with("Entry")); 16 | 17 | assert_eq!(0, d.message.extension.len()); 18 | assert_eq!(0, d.message.extension_range.len()); 19 | assert_eq!(0, d.message.nested_type.len()); 20 | assert_eq!(0, d.message.enum_type.len()); 21 | 22 | assert_eq!(2, d.fields().len()); 23 | let key = d.fields()[0].clone(); 24 | let value = d.fields()[1].clone(); 25 | 26 | assert_eq!("key", key.name()); 27 | assert_eq!("value", value.name()); 28 | 29 | assert_eq!(1, key.number()); 30 | assert_eq!(2, value.number()); 31 | 32 | assert_eq!( 33 | field_descriptor_proto::Label::LABEL_OPTIONAL, 34 | key.field.get_label() 35 | ); 36 | assert_eq!( 37 | field_descriptor_proto::Label::LABEL_OPTIONAL, 38 | value.field.get_label() 39 | ); 40 | 41 | Some((key, value)) 42 | } else { 43 | None 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /protobuf-codegen/src/case_convert.rs: -------------------------------------------------------------------------------- 1 | // copy-paste from Google Protobuf 2 | // must be kept in sync with Google for JSON interop 3 | pub fn camel_case(input: &str) -> String { 4 | let mut capitalize_next = true; 5 | let mut result = String::new(); 6 | result.reserve(input.len()); 7 | 8 | for c in input.chars() { 9 | if c == '_' { 10 | capitalize_next = true; 11 | } else if capitalize_next { 12 | result.push(c.to_ascii_uppercase()); 13 | capitalize_next = false; 14 | } else { 15 | result.push(c); 16 | } 17 | } 18 | 19 | result 20 | } 21 | 22 | pub fn snake_case(input: &str) -> String { 23 | let mut result = String::new(); 24 | 25 | let mut last_lower = false; 26 | 27 | for c in input.chars() { 28 | if c.is_ascii_uppercase() && last_lower { 29 | result.push('_'); 30 | } 31 | result.push(c.to_ascii_lowercase()); 32 | last_lower = c.is_lowercase(); 33 | } 34 | 35 | result 36 | } 37 | 38 | #[cfg(test)] 39 | mod test { 40 | use super::*; 41 | 42 | #[test] 43 | fn test_camel_case() { 44 | assert_eq!("FooBarBazQuxQUUX", camel_case("foo_barBaz_QuxQUUX")); 45 | assert_eq!("FooBarBazQuxQUUX", camel_case("Foo_barBaz_QuxQUUX")); 46 | } 47 | 48 | #[test] 49 | fn test_snake_case() { 50 | assert_eq!("foo_bar_baz_qux_quux", snake_case("foo_barBaz_QuxQUUX")); 51 | assert_eq!("foo_bar_baz_qux_quux", snake_case("Foo_barBaz_QuxQUUX")); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /protobuf-test/src/common/v2/test_ident_pb.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto2"; 2 | 3 | import "google/protobuf/descriptor.proto"; 4 | 5 | package test_ident; 6 | 7 | // rust types defined in prelude 8 | 9 | message Vec { } 10 | 11 | message String { } 12 | 13 | message Option { } 14 | message None { } 15 | message Some { } 16 | 17 | message Message { } 18 | 19 | // rust keywords 20 | 21 | message struct { } 22 | 23 | message Self { 24 | optional string s = 1; 25 | } 26 | 27 | message Outer { 28 | message fn {} 29 | } 30 | 31 | // oneof named type 32 | 33 | message TestType { 34 | oneof type { 35 | string s = 1; 36 | } 37 | repeated string struct = 2; 38 | repeated uint32 ref = 3; 39 | } 40 | 41 | // enum value which is a keyword 42 | 43 | enum MyLittleEnum { 44 | UNKNOWN = 0; 45 | fn = 2; 46 | self = 3; 47 | } 48 | 49 | message MessageRefencesEnum { 50 | optional MyLittleEnum e1 = 1; 51 | required MyLittleEnum e2 = 2; 52 | repeated MyLittleEnum e3 = 3; 53 | oneof one_enum { 54 | MyLittleEnum e4 = 4; 55 | } 56 | } 57 | 58 | enum EnumWithDefaultValueReserved { 59 | in = 0; 60 | } 61 | 62 | message MessageReferencesEnumWithDefaultValueReserved { 63 | optional EnumWithDefaultValueReserved e1 = 1; 64 | required EnumWithDefaultValueReserved e2 = 2; 65 | repeated EnumWithDefaultValueReserved e3 = 3; 66 | oneof one_enum { 67 | EnumWithDefaultValueReserved e4 = 4; 68 | } 69 | } 70 | 71 | extend google.protobuf.EnumValueOptions { 72 | optional string type = 51234; 73 | } 74 | -------------------------------------------------------------------------------- /protobuf-test/src/common/v2/test_ext.rs: -------------------------------------------------------------------------------- 1 | use protobuf::prelude::*; 2 | use protobuf::Message; 3 | 4 | use super::test_ext_pb::*; 5 | 6 | #[test] 7 | fn test_get() { 8 | let descriptor = MyMessage::descriptor_static(); 9 | let message = descriptor.get_proto().options.get_message(); 10 | assert_eq!(10.5, exts::double_field.get(message).unwrap_or_default()); 11 | assert_eq!(-8.5, exts::float_field.get(message).unwrap_or_default()); 12 | assert_eq!(-3, exts::int32_field.get(message).unwrap_or_default()); 13 | assert_eq!(-13, exts::int64_field.get(message).unwrap_or_default()); 14 | assert_eq!(-4, exts::sint32_field.get(message).unwrap_or_default()); 15 | assert_eq!(-14, exts::sint64_field.get(message).unwrap_or_default()); 16 | assert_eq!(5, exts::uint32_field.get(message).unwrap_or_default()); 17 | assert_eq!(15, exts::uint64_field.get(message).unwrap_or_default()); 18 | assert_eq!(6, exts::fixed32_field.get(message).unwrap_or_default()); 19 | assert_eq!(16, exts::fixed64_field.get(message).unwrap_or_default()); 20 | assert_eq!(7, exts::sfixed32_field.get(message).unwrap_or_default()); 21 | assert_eq!(-17, exts::sfixed64_field.get(message).unwrap_or_default()); 22 | assert_eq!(true, exts::bool_field.get(message).unwrap_or_default()); 23 | assert_eq!("Hello world!", exts::string_field.get(message).unwrap_or_default()); 24 | if false { 25 | // TODO: only implemented in `protoc`-based codegen 26 | assert_eq!(TestEnum::RED, exts::enum_field.get(message).unwrap_or_default().unwrap()); 27 | assert_eq!(22, exts::message_field.get(message).unwrap().get_n()); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /protobuf/src/ext.rs: -------------------------------------------------------------------------------- 1 | //! Utilities to support "extension" fields. 2 | //! 3 | //! Extensions are [described in the official protobuf documentation][exts]. 4 | //! 5 | //! [exts]: https://developers.google.com/protocol-buffers/docs/proto#extensions 6 | 7 | use std::marker::PhantomData; 8 | 9 | use crate::core::Message; 10 | use crate::reflect::runtime_types::RuntimeType; 11 | use crate::reflect::types::ProtobufType; 12 | 13 | /// Optional ext field 14 | pub struct ExtFieldOptional { 15 | /// Extension field number 16 | pub field_number: u32, 17 | /// Marker 18 | // TODO: hide 19 | pub phantom: PhantomData<(M, T)>, 20 | } 21 | 22 | /// Repeated ext field 23 | pub struct ExtFieldRepeated { 24 | /// Extension field number 25 | pub field_number: u32, 26 | /// Extension field number 27 | // TODO: hide 28 | pub phantom: PhantomData<(M, T)>, 29 | } 30 | 31 | impl ExtFieldOptional { 32 | /// Get a copy of value from a message. 33 | /// 34 | /// Extension data is stored in [`UnknownFields`](crate::UnknownFields). 35 | pub fn get(&self, m: &M) -> Option<::Value> { 36 | m.get_unknown_fields() 37 | .get(self.field_number) 38 | .and_then(T::get_from_unknown) 39 | } 40 | } 41 | 42 | impl ExtFieldRepeated { 43 | /// Get a copy of value from a message (**not implemented**). 44 | pub fn get(&self, _m: &M) -> Vec<::Value> { 45 | // TODO 46 | unimplemented!() 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /protobuf/src/text_format/lexer/float.rs: -------------------------------------------------------------------------------- 1 | use std::f64; 2 | 3 | #[derive(Debug)] 4 | pub enum ProtobufFloatParseError { 5 | EmptyString, 6 | CannotParseFloat, 7 | } 8 | 9 | pub type ProtobufFloatParseResult = Result; 10 | 11 | pub const PROTOBUF_NAN: &str = "nan"; 12 | pub const PROTOBUF_INF: &str = "inf"; 13 | 14 | /// Format float as in protobuf `.proto` files 15 | pub fn format_protobuf_float(f: f64) -> String { 16 | if f.is_nan() { 17 | PROTOBUF_NAN.to_owned() 18 | } else if f.is_infinite() { 19 | if f > 0.0 { 20 | format!("{}", PROTOBUF_INF) 21 | } else { 22 | format!("-{}", PROTOBUF_INF) 23 | } 24 | } else { 25 | // TODO: make sure doesn't lose precision 26 | format!("{:?}", f) 27 | } 28 | } 29 | 30 | /// Parse float from `.proto` format 31 | pub fn parse_protobuf_float(s: &str) -> ProtobufFloatParseResult { 32 | if s.is_empty() { 33 | return Err(ProtobufFloatParseError::EmptyString); 34 | } 35 | if s == PROTOBUF_NAN { 36 | return Ok(f64::NAN); 37 | } 38 | if s == PROTOBUF_INF || s == format!("+{}", PROTOBUF_INF) { 39 | return Ok(f64::INFINITY); 40 | } 41 | if s == format!("-{}", PROTOBUF_INF) { 42 | return Ok(f64::NEG_INFINITY); 43 | } 44 | match s.parse() { 45 | Ok(f) => Ok(f), 46 | Err(_) => Err(ProtobufFloatParseError::CannotParseFloat), 47 | } 48 | } 49 | 50 | #[cfg(test)] 51 | mod test { 52 | use super::*; 53 | 54 | #[test] 55 | fn test_format_protobuf_float() { 56 | assert_eq!("10.0", format_protobuf_float(10.0)); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /protobuf/benches/coded_output_stream.rs: -------------------------------------------------------------------------------- 1 | // `cargo test --benches` and `#[feature(test)]` work only in nightly 2 | #![cfg(rustc_nightly)] 3 | #![feature(test)] 4 | 5 | extern crate protobuf; 6 | extern crate test; 7 | 8 | use self::test::Bencher; 9 | use protobuf::CodedOutputStream; 10 | 11 | #[inline] 12 | fn buffer_write_byte(os: &mut CodedOutputStream) { 13 | for i in 0..10 { 14 | os.write_raw_byte(test::black_box(i as u8)).unwrap(); 15 | } 16 | os.flush().unwrap(); 17 | } 18 | 19 | #[inline] 20 | fn buffer_write_bytes(os: &mut CodedOutputStream) { 21 | for _ in 0..10 { 22 | os.write_raw_bytes(test::black_box(b"1234567890")).unwrap(); 23 | } 24 | os.flush().unwrap(); 25 | } 26 | 27 | #[bench] 28 | fn bench_buffer(b: &mut Bencher) { 29 | b.iter(|| { 30 | let mut v = Vec::new(); 31 | { 32 | let mut os = CodedOutputStream::new(&mut v); 33 | buffer_write_byte(&mut os); 34 | } 35 | v 36 | }); 37 | } 38 | 39 | #[bench] 40 | fn bench_buffer_bytes(b: &mut Bencher) { 41 | b.iter(|| { 42 | let mut v = Vec::new(); 43 | { 44 | let mut os = CodedOutputStream::new(&mut v); 45 | buffer_write_bytes(&mut os); 46 | } 47 | v 48 | }); 49 | } 50 | 51 | #[bench] 52 | fn bench_write_raw_varint_32(b: &mut Bencher) { 53 | let mut v = Vec::with_capacity(10_000); 54 | b.iter(|| { 55 | v.clear(); 56 | { 57 | let mut os = CodedOutputStream::new(&mut v); 58 | for i in 0..1000 { 59 | os.write_raw_varint32(i * 139 % 1000).unwrap(); 60 | } 61 | } 62 | v.len() 63 | }) 64 | } 65 | -------------------------------------------------------------------------------- /protobuf-test/src/common/v2/test_fmt_json_well_known_pb.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto2"; 2 | 3 | import "google/protobuf/any.proto"; 4 | import "google/protobuf/api.proto"; 5 | import "google/protobuf/duration.proto"; 6 | import "google/protobuf/empty.proto"; 7 | import "google/protobuf/field_mask.proto"; 8 | import "google/protobuf/source_context.proto"; 9 | import "google/protobuf/struct.proto"; 10 | import "google/protobuf/timestamp.proto"; 11 | import "google/protobuf/type.proto"; 12 | import "google/protobuf/wrappers.proto"; 13 | 14 | import "rustproto.proto"; 15 | option (rustproto.generate_accessors_all) = true; 16 | 17 | 18 | message TestFmtJsonWellKnownTypes { 19 | optional .google.protobuf.Duration duration = 3; 20 | optional .google.protobuf.Timestamp timestamp = 4; 21 | optional .google.protobuf.FieldMask field_mask = 5; 22 | repeated .google.protobuf.NullValue null_values = 10; 23 | optional .google.protobuf.Value value = 12; 24 | optional .google.protobuf.ListValue list_value = 13; 25 | optional .google.protobuf.Struct struct_value = 14; 26 | optional .google.protobuf.Any any_value = 15; 27 | 28 | optional .google.protobuf.DoubleValue double_value = 31; 29 | optional .google.protobuf.FloatValue float_value = 32; 30 | optional .google.protobuf.Int64Value int64_value = 33; 31 | optional .google.protobuf.UInt64Value uint64_value = 34; 32 | optional .google.protobuf.Int32Value int32_value = 35; 33 | optional .google.protobuf.UInt32Value uint32_value = 36; 34 | optional .google.protobuf.BoolValue bool_value = 37; 35 | optional .google.protobuf.StringValue string_value = 38; 36 | optional .google.protobuf.BytesValue bytes_value = 39; 37 | } 38 | -------------------------------------------------------------------------------- /protobuf/src/buf_read_or_reader.rs: -------------------------------------------------------------------------------- 1 | //! `BufRead` pointer or `BufReader` owned. 2 | 3 | use std::io::{BufRead, BufReader, Read}; 4 | use std::io; 5 | 6 | /// Helper type to simplify `BufReadIter` implementation. 7 | pub(crate) enum BufReadOrReader<'a> { 8 | BufReader(BufReader<&'a mut dyn Read>), 9 | BufRead(&'a mut dyn BufRead), 10 | } 11 | 12 | impl<'a> Read for BufReadOrReader<'a> { 13 | fn read(&mut self, buf: &mut [u8]) -> Result { 14 | match self { 15 | BufReadOrReader::BufReader(r) => r.read(buf), 16 | BufReadOrReader::BufRead(r) => r.read(buf), 17 | } 18 | } 19 | 20 | fn read_to_end(&mut self, buf: &mut Vec) -> Result { 21 | match self { 22 | BufReadOrReader::BufReader(r) => r.read_to_end(buf), 23 | BufReadOrReader::BufRead(r) => r.read_to_end(buf), 24 | } 25 | } 26 | 27 | fn read_exact(&mut self, buf: &mut [u8]) -> Result<(), io::Error> { 28 | match self { 29 | BufReadOrReader::BufReader(r) => r.read_exact(buf), 30 | BufReadOrReader::BufRead(r) => r.read_exact(buf), 31 | } 32 | } 33 | } 34 | 35 | impl<'a> BufRead for BufReadOrReader<'a> { 36 | fn fill_buf(&mut self) -> Result<&[u8], io::Error> { 37 | match self { 38 | BufReadOrReader::BufReader(r) => r.fill_buf(), 39 | BufReadOrReader::BufRead(r) => r.fill_buf(), 40 | } 41 | } 42 | 43 | fn consume(&mut self, amt: usize) { 44 | match self { 45 | BufReadOrReader::BufReader(r) => r.consume(amt), 46 | BufReadOrReader::BufRead(r) => r.consume(amt), 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /protobuf/src/zigzag.rs: -------------------------------------------------------------------------------- 1 | // ZigZag endoging used for efficient transfer of signed integers 2 | // https://developers.google.com/protocol-buffers/docs/encoding#types 3 | 4 | pub fn decode_zig_zag_32(n: u32) -> i32 { 5 | ((n >> 1) as i32) ^ (-((n & 1) as i32)) 6 | } 7 | 8 | pub fn decode_zig_zag_64(n: u64) -> i64 { 9 | ((n >> 1) as i64) ^ (-((n & 1) as i64)) 10 | } 11 | 12 | pub fn encode_zig_zag_32(n: i32) -> u32 { 13 | ((n << 1) ^ (n >> 31)) as u32 14 | } 15 | 16 | pub fn encode_zig_zag_64(n: i64) -> u64 { 17 | ((n << 1) ^ (n >> 63)) as u64 18 | } 19 | 20 | #[cfg(test)] 21 | mod test { 22 | 23 | use super::decode_zig_zag_32; 24 | use super::decode_zig_zag_64; 25 | use super::encode_zig_zag_32; 26 | use super::encode_zig_zag_64; 27 | 28 | #[test] 29 | fn test_zig_zag() { 30 | fn test_zig_zag_pair_64(decoded: i64, encoded: u64) { 31 | assert_eq!(decoded, decode_zig_zag_64(encoded)); 32 | assert_eq!(encoded, encode_zig_zag_64(decoded)); 33 | } 34 | 35 | fn test_zig_zag_pair(decoded: i32, encoded: u32) { 36 | assert_eq!(decoded, decode_zig_zag_32(encoded)); 37 | assert_eq!(encoded, encode_zig_zag_32(decoded)); 38 | test_zig_zag_pair_64(decoded as i64, encoded as u64); 39 | } 40 | 41 | test_zig_zag_pair(0, 0); 42 | test_zig_zag_pair(-1, 1); 43 | test_zig_zag_pair(1, 2); 44 | test_zig_zag_pair(-2, 3); 45 | test_zig_zag_pair(2147483647, 4294967294); 46 | test_zig_zag_pair(-2147483648, 4294967295); 47 | test_zig_zag_pair_64(9223372036854775807, 18446744073709551614); 48 | test_zig_zag_pair_64(-9223372036854775808, 18446744073709551615); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to rust-protobuf 2 | 3 | ## Code of conduct 4 | 5 | You are welcome to contribute code of conduct. 6 | 7 | Meanwhile, please be polite to everyone. 8 | 9 | ## I just want to ask a question 10 | 11 | Feel free to open an issue to ask a question, the volume of questions is low, 12 | so it's OK at the moment. But please don't expect prompt answer. 13 | 14 | ## I have found a bug 15 | 16 | Please open an issue. When reporting a bug please include minimal example 17 | providing as much information as possible. In particular, please specify: 18 | 19 | * exact proto file 20 | * generated file 21 | * rust-protobuf version 22 | * command which was used to generate code (ideally, temporary standalone repository) 23 | * what is version of `protoc` command 24 | * what is operating system 25 | 26 | ## Tests 27 | 28 | Most of code changes should be accompanied by tests. 29 | 30 | Most tests can be executed by invoking `cargo test` in `protobuf-test` directory. 31 | 32 | ## Codegen 33 | 34 | If you change code generator, tests will check that code generator works correctly. 35 | 36 | However, before submitting a PR, it's necessary to regenerate generated files 37 | shipped with rust-protobuf, notably, `descriptor.rs`. 38 | 39 | This can be done by invoking a script `protobuf/regenerate.sh`. 40 | 41 | ## Performance improvements 42 | 43 | Are always welcome, especially if they are backward-compatible. 44 | 45 | ## API changes, generated code changes 46 | 47 | There are tons 48 | 49 | ## What if I just want to do something useful 50 | 51 | Some issues in the tracker are marked with 52 | 53 | ## Help wanted 54 | 55 | Most of all documentation is needed, any changes to rustdoc or markdown pages on github are welcome. 56 | -------------------------------------------------------------------------------- /protobuf/regenerate.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh -ex 2 | 3 | cd $(dirname $0) 4 | 5 | die() { 6 | echo "$@" >&2 7 | exit 1 8 | } 9 | 10 | protoc_ver=$(protoc --version) 11 | case "$protoc_ver" in 12 | "libprotoc 3"*) ;; 13 | *) 14 | die "you need to use protobuf 3 to regenerate .rs from .proto" 15 | ;; 16 | esac 17 | 18 | cargo build --manifest-path=../protobuf-codegen/Cargo.toml 19 | 20 | where_am_i=$(cd ..; pwd) 21 | 22 | rm -rf tmp-generated 23 | mkdir tmp-generated 24 | 25 | case `uname` in 26 | Linux) 27 | exe_suffix="" 28 | ;; 29 | MSYS_NT*) 30 | exe_suffix=".exe" 31 | ;; 32 | esac 33 | 34 | protoc \ 35 | --plugin=protoc-gen-rust="$where_am_i/target/debug/protoc-gen-rust$exe_suffix" \ 36 | --rust_out tmp-generated \ 37 | --rust_opt 'serde_derive=true serde_derive_cfg=serde inside_protobuf=true' \ 38 | -I../proto \ 39 | ../proto/google/protobuf/*.proto \ 40 | ../proto/google/protobuf/compiler/* \ 41 | ../proto/rustproto.proto 42 | 43 | mv tmp-generated/descriptor.rs tmp-generated/plugin.rs tmp-generated/rustproto.rs src/ 44 | mv tmp-generated/*.rs src/well_known_types/ 45 | ( 46 | cd src/well_known_types 47 | exec > mod.rs 48 | echo "// This file is generated. Do not edit" 49 | echo '//! Generated code for "well known types"' 50 | echo "//!" 51 | echo "//! [This document](https://developers.google.com/protocol-buffers/docs/reference/google.protobuf) describes these types." 52 | 53 | mod_list() { 54 | ls | grep -v mod.rs | sed -e 's,\.rs$,,' 55 | } 56 | 57 | echo 58 | mod_list | sed -e 's,^,mod ,; s,$,;,' 59 | 60 | echo 61 | mod_list | while read mod; do 62 | echo "pub use self::$mod::*;" 63 | done 64 | ) 65 | 66 | # vim: set ts=4 sw=4 et: 67 | -------------------------------------------------------------------------------- /protobuf-test/src/v2/test_default_values.rs: -------------------------------------------------------------------------------- 1 | use std::f32; 2 | use std::f64; 3 | 4 | use super::test_default_values_pb::*; 5 | 6 | #[test] 7 | fn test_default_value_simple() { 8 | let d = TestDefaultValues::new(); 9 | assert_eq!(1.0, d.get_double_field()); 10 | assert_eq!(2.0, d.get_float_field()); 11 | assert_eq!(3, d.get_int32_field()); 12 | assert_eq!(4, d.get_int64_field()); 13 | assert_eq!(5, d.get_uint32_field()); 14 | assert_eq!(6, d.get_uint64_field()); 15 | assert_eq!(7, d.get_sint32_field()); 16 | assert_eq!(8, d.get_sint64_field()); 17 | assert_eq!(9, d.get_fixed32_field()); 18 | assert_eq!(10, d.get_fixed64_field()); 19 | assert_eq!(11, d.get_sfixed32_field()); 20 | assert_eq!(12, d.get_sfixed64_field()); 21 | assert_eq!(true, d.get_bool_field()); 22 | assert_eq!("abc\n22", d.get_string_field()); 23 | assert_eq!(b"cde\n33", d.get_bytes_field()); 24 | assert_eq!(EnumForDefaultValue::TWO, d.get_enum_field()); 25 | assert_eq!(EnumForDefaultValue::ONE, d.get_enum_field_without_default()); 26 | } 27 | 28 | #[test] 29 | fn test_default_value_extreme() { 30 | let d = TestExtremeDefaultValues::new(); 31 | assert_eq!(f64::INFINITY, d.get_inf_double()); 32 | assert_eq!(f64::NEG_INFINITY, d.get_neg_inf_double()); 33 | assert!(d.get_nan_double().is_nan()); 34 | assert_eq!(f32::INFINITY, d.get_inf_float()); 35 | assert_eq!(f32::NEG_INFINITY, d.get_neg_inf_float()); 36 | assert!(d.get_nan_float().is_nan()); 37 | assert_eq!( 38 | b"\0\x01\x07\x08\x0c\n\r\t\x0b\\\'\"\xfe", 39 | d.get_escaped_bytes() 40 | ); 41 | assert_eq!("'", d.get_quote1()); 42 | assert_eq!("\"", d.get_quote2()); 43 | assert_eq!(b"'", d.get_bquote1()); 44 | assert_eq!(b"\"", d.get_bquote2()); 45 | } 46 | -------------------------------------------------------------------------------- /protobuf-codegen/src/well_known_types.rs: -------------------------------------------------------------------------------- 1 | use crate::protobuf_name::ProtobufAbsolutePath; 2 | use crate::protobuf_name::ProtobufRelativePath; 3 | 4 | static NAMES: &'static [&'static str] = &[ 5 | "Any", 6 | "Api", 7 | "BoolValue", 8 | "BytesValue", 9 | "DoubleValue", 10 | "Duration", 11 | "Empty", 12 | "Enum", 13 | "EnumValue", 14 | "Field", 15 | // TODO: dotted names 16 | "Field.Cardinality", 17 | "Field.Kind", 18 | "FieldMask", 19 | "FloatValue", 20 | "Int32Value", 21 | "Int64Value", 22 | "ListValue", 23 | "Method", 24 | "Mixin", 25 | "NullValue", 26 | "Option", 27 | "SourceContext", 28 | "StringValue", 29 | "Struct", 30 | "Syntax", 31 | "Timestamp", 32 | "Type", 33 | "UInt32Value", 34 | "UInt64Value", 35 | "Value", 36 | ]; 37 | 38 | fn is_well_known_type(name: &ProtobufRelativePath) -> bool { 39 | NAMES.iter().any(|&n| n == name.path) 40 | } 41 | 42 | pub fn is_well_known_type_full(name: &ProtobufAbsolutePath) -> Option { 43 | if let Some(ref rem) = name.remove_prefix(&ProtobufAbsolutePath::from(".google.protobuf")) { 44 | if is_well_known_type(rem) { 45 | Some(rem.clone()) 46 | } else { 47 | None 48 | } 49 | } else { 50 | None 51 | } 52 | } 53 | 54 | #[cfg(test)] 55 | mod test { 56 | use super::*; 57 | 58 | #[test] 59 | fn test_is_well_known_type_full() { 60 | assert_eq!( 61 | Some(ProtobufRelativePath::from("BoolValue")), 62 | is_well_known_type_full(&ProtobufAbsolutePath::from(".google.protobuf.BoolValue")) 63 | ); 64 | assert_eq!( 65 | None, 66 | is_well_known_type_full(&ProtobufAbsolutePath::from(".google.protobuf.Fgfg")) 67 | ); 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /protobuf-codegen/README.md: -------------------------------------------------------------------------------- 1 | # protobuf-codegen 2 | 3 | This crate contains protobuf code generator and a `protoc-gen-rust` `protoc` plugin. 4 | 5 | ## protoc-gen-rust 6 | 7 | `protoc-gen-rust` implements standard protobuf `protoc` plugin conventions. 8 | 9 | Probably you do not want to use it directly in Rust environment, there are easier to use alternatives: 10 | 11 | * [protoc-rust crate](https://github.com/stepancheg/rust-protobuf/tree/master/protoc-rust) 12 | which can be invoked programmatically from `build.rs` of your project 13 | which requires only `protoc` in `$PATH` but not `protoc-gen-rust`. 14 | * [protobuf-codegen-pure crate](https://github.com/stepancheg/rust-protobuf/tree/master/protobuf-codegen-pure) 15 | which behaves like protoc-rust, but does not depend on `protoc` binary 16 | 17 | ## But if you really want to use that plugin, here's the instruction 18 | 19 | (Note `protoc` can be invoked programmatically with 20 | [protoc crate](https://github.com/stepancheg/rust-protobuf/tree/master/protoc/)) 21 | 22 | 0) Install protobuf for `protoc` binary. 23 | 24 | On OS X [Homebrew](https://github.com/Homebrew/brew) can be used: 25 | 26 | ``` 27 | brew install protobuf 28 | ``` 29 | 30 | On Ubuntu, `protobuf-compiler` package can be installed: 31 | 32 | ``` 33 | apt-get install protobuf-compiler 34 | ``` 35 | 36 | Protobuf is needed only for code generation, `rust-protobuf` runtime 37 | does not use `protobuf` library. 38 | 39 | 1) Install `protoc-gen-rust` program (which is `protoc` plugin) 40 | 41 | It can be installed either from source or with `cargo install protobuf-codegen` command. 42 | 43 | 2) Add `protoc-gen-rust` to $PATH 44 | 45 | If you installed it with cargo, it should be 46 | 47 | ``` 48 | PATH="$HOME/.cargo/bin:$PATH" 49 | ``` 50 | 51 | 3) Generate .rs files: 52 | 53 | ``` 54 | protoc --rust_out . foo.proto 55 | ``` 56 | 57 | This will generate .rs files in current directory. 58 | -------------------------------------------------------------------------------- /protobuf-test/src/common/v2/test_ext_pb.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto2"; 2 | 3 | package test_ext; 4 | 5 | import "google/protobuf/descriptor.proto"; 6 | import "rustproto.proto"; 7 | option (rustproto.generate_accessors_all) = true; 8 | 9 | 10 | message SubM { 11 | optional int32 n = 1; 12 | } 13 | 14 | enum TestEnum { 15 | UNDEFINED = 0; 16 | RED = 1; 17 | BLUE = 2; 18 | GREEN = 3; 19 | } 20 | 21 | 22 | extend google.protobuf.MessageOptions { 23 | optional double double_field = 50001; 24 | optional float float_field = 50002; 25 | optional int32 int32_field = 50003; 26 | optional int64 int64_field = 50004; 27 | optional uint32 uint32_field = 50005; 28 | optional uint64 uint64_field = 50006; 29 | optional sint32 sint32_field = 50007; 30 | optional sint64 sint64_field = 50008; 31 | optional fixed32 fixed32_field = 50009; 32 | optional fixed64 fixed64_field = 50010; 33 | optional sfixed32 sfixed32_field = 50011; 34 | optional sfixed64 sfixed64_field = 50012; 35 | optional bool bool_field = 50013; 36 | optional string string_field = 50014; 37 | optional bytes bytes_field = 50015; 38 | optional TestEnum enum_field = 50016; 39 | optional SubM message_field = 50017; 40 | } 41 | 42 | message MyMessage { 43 | option (double_field) = 10.5; 44 | option (float_field) = -8.5; 45 | option (int32_field) = -3; 46 | option (int64_field) = -13; 47 | option (sint32_field) = -4; 48 | option (sint64_field) = -14; 49 | option (uint32_field) = 5; 50 | option (uint64_field) = 15; 51 | option (fixed32_field) = 6; 52 | option (fixed64_field) = 16; 53 | option (sfixed32_field) = 7; 54 | option (sfixed64_field) = -17; 55 | option (bool_field) = true; 56 | option (string_field) = "Hello world!"; 57 | option (bytes_field) = "bytes"; 58 | option (enum_field) = RED; 59 | option (message_field) = { n: 22 }; 60 | } 61 | -------------------------------------------------------------------------------- /protobuf-test-common/src/serialize_deserialize_tests.rs: -------------------------------------------------------------------------------- 1 | use crate::hex::decode_hex; 2 | use crate::hex::encode_hex; 3 | 4 | use protobuf::*; 5 | 6 | pub fn test_serialize_deserialize_length_delimited(msg: &M) { 7 | let serialized_bytes = msg.write_length_delimited_to_bytes().unwrap(); 8 | let mut is = CodedInputStream::from_bytes(&serialized_bytes); 9 | let parsed = is.read_message().unwrap(); 10 | is.check_eof().unwrap(); 11 | assert_eq!(*msg, parsed); 12 | } 13 | 14 | pub fn test_serialize_deserialize_no_hex(msg: &M) { 15 | let serialized_bytes = msg.write_to_bytes().unwrap(); 16 | let parsed = parse_from_bytes::(&serialized_bytes).unwrap(); 17 | assert_eq!(*msg, parsed); 18 | } 19 | 20 | pub fn test_serialize_deserialize(hex: &str, msg: &M) { 21 | let expected_bytes = decode_hex(hex); 22 | let expected_hex = encode_hex(&expected_bytes); 23 | let serialized = msg.write_to_bytes().unwrap(); 24 | let serialized_hex = encode_hex(&serialized); 25 | assert_eq!( 26 | expected_hex, 27 | serialized_hex, 28 | "message {}", 29 | M::descriptor_static().name() 30 | ); 31 | let parsed = parse_from_bytes::(&expected_bytes).unwrap(); 32 | assert_eq!(*msg, parsed); 33 | 34 | assert_eq!(expected_bytes.len(), msg.compute_size() as usize); 35 | 36 | test_serialize_deserialize_length_delimited(msg); 37 | } 38 | 39 | pub fn test_deserialize(hex: &str, msg: &M) { 40 | let bytes = decode_hex(hex); 41 | let parsed = parse_from_bytes::(&bytes).unwrap(); 42 | assert_eq!(*msg, parsed); 43 | } 44 | 45 | pub fn test_serialize(hex: &str, msg: &M) { 46 | let hex = encode_hex(&decode_hex(hex)); 47 | 48 | let serialized = msg.write_to_bytes().unwrap(); 49 | let serialized_hex = encode_hex(&serialized); 50 | 51 | assert_eq!(serialized_hex, hex); 52 | } 53 | -------------------------------------------------------------------------------- /protobuf-codegen/src/file.rs: -------------------------------------------------------------------------------- 1 | use crate::rust; 2 | use crate::rust_name::RustIdent; 3 | use crate::strx; 4 | 5 | // Copy-pasted from libsyntax. 6 | fn ident_start(c: char) -> bool { 7 | (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '_' 8 | } 9 | 10 | // Copy-pasted from libsyntax. 11 | fn ident_continue(c: char) -> bool { 12 | (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') || c == '_' 13 | } 14 | 15 | pub(crate) fn proto_path_to_rust_mod(path: &str) -> RustIdent { 16 | let without_dir = strx::remove_to(path, '/'); 17 | let without_suffix = strx::remove_suffix(without_dir, ".proto"); 18 | 19 | let name = without_suffix 20 | .chars() 21 | .enumerate() 22 | .map(|(i, c)| { 23 | let valid = if i == 0 { 24 | ident_start(c) 25 | } else { 26 | ident_continue(c) 27 | }; 28 | if valid { 29 | c 30 | } else { 31 | '_' 32 | } 33 | }) 34 | .collect::(); 35 | 36 | let name = if rust::is_rust_keyword(&name) { 37 | format!("{}_pb", name) 38 | } else { 39 | name 40 | }; 41 | RustIdent::from(name) 42 | } 43 | 44 | #[cfg(test)] 45 | mod test { 46 | 47 | use super::proto_path_to_rust_mod; 48 | use crate::rust_name::RustIdent; 49 | 50 | #[test] 51 | fn test_mod_path_proto_ext() { 52 | assert_eq!( 53 | RustIdent::from("proto"), 54 | proto_path_to_rust_mod("proto.proto") 55 | ); 56 | } 57 | 58 | #[test] 59 | fn test_mod_path_unknown_ext() { 60 | assert_eq!( 61 | RustIdent::from("proto_proto3"), 62 | proto_path_to_rust_mod("proto.proto3") 63 | ); 64 | } 65 | 66 | #[test] 67 | fn test_mod_path_empty_ext() { 68 | assert_eq!(RustIdent::from("proto"), proto_path_to_rust_mod("proto")); 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /protobuf-test/src/google/protobuf/unittest_no_arena_import.proto: -------------------------------------------------------------------------------- 1 | // Protocol Buffers - Google's data interchange format 2 | // Copyright 2008 Google Inc. All rights reserved. 3 | // https://developers.google.com/protocol-buffers/ 4 | // 5 | // Redistribution and use in source and binary forms, with or without 6 | // modification, are permitted provided that the following conditions are 7 | // met: 8 | // 9 | // * Redistributions of source code must retain the above copyright 10 | // notice, this list of conditions and the following disclaimer. 11 | // * Redistributions in binary form must reproduce the above 12 | // copyright notice, this list of conditions and the following disclaimer 13 | // in the documentation and/or other materials provided with the 14 | // distribution. 15 | // * Neither the name of Google Inc. nor the names of its 16 | // contributors may be used to endorse or promote products derived from 17 | // this software without specific prior written permission. 18 | // 19 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | 31 | syntax = "proto2"; 32 | 33 | package proto2_arena_unittest; 34 | 35 | message ImportNoArenaNestedMessage { 36 | optional int32 d = 1; 37 | }; 38 | -------------------------------------------------------------------------------- /protobuf/src/reflect/find_message_or_enum.rs: -------------------------------------------------------------------------------- 1 | use crate::descriptor::FileDescriptorProto; 2 | use crate::descriptor::DescriptorProto; 3 | use crate::descriptor::EnumDescriptorProto; 4 | 5 | pub(crate) enum MessageOrEnum<'a> { 6 | Message(&'a DescriptorProto), 7 | Enum(&'a EnumDescriptorProto), 8 | } 9 | 10 | impl<'a> MessageOrEnum<'a> { 11 | fn from_two_options(m: Option<&'a DescriptorProto>, e: Option<&'a EnumDescriptorProto>) 12 | -> MessageOrEnum<'a> 13 | { 14 | match (m, e) { 15 | (Some(_), Some(_)) => panic!("enum and message with the same name"), 16 | (Some(m), None) => MessageOrEnum::Message(m), 17 | (None, Some(e)) => MessageOrEnum::Enum(e), 18 | (None, None) => panic!("not found"), 19 | } 20 | } 21 | } 22 | 23 | pub(crate) fn find_message_or_enum<'a>(file: &'a FileDescriptorProto, name_to_package: &str) 24 | -> (String, MessageOrEnum<'a>) 25 | { 26 | let mut path = name_to_package.split('.'); 27 | let first = path.next().unwrap(); 28 | let child_message = file.message_type.iter().find(|m| m.get_name() == first); 29 | let child_enum = file.enum_type.iter().find(|e| e.get_name() == first); 30 | 31 | let mut package_to_name = String::new(); 32 | let mut me = MessageOrEnum::from_two_options(child_message, child_enum); 33 | 34 | for name in path { 35 | let message = match me { 36 | MessageOrEnum::Message(m) => m, 37 | MessageOrEnum::Enum(_) => panic!("enum has no children"), 38 | }; 39 | 40 | if !package_to_name.is_empty() { 41 | package_to_name.push_str("."); 42 | } 43 | package_to_name.push_str(message.get_name()); 44 | 45 | let child_message = message.nested_type.iter().find(|m| m.get_name() == name); 46 | let child_enum = message.enum_type.iter().find(|e| e.get_name() == name); 47 | me = MessageOrEnum::from_two_options(child_message, child_enum) 48 | } 49 | 50 | (package_to_name, me) 51 | } 52 | -------------------------------------------------------------------------------- /FAQ.md: -------------------------------------------------------------------------------- 1 | # Frequently asked questions 2 | 3 | ## Questions about Protocol Buffers 4 | 5 | Protocol Buffers is designed and maintained by Google. 6 | 7 | Google has very thorough documentation including [FAQ](https://developers.google.com/protocol-buffers/docs/faq). 8 | 9 | If your question is not rust-protobuf-specific, it's likely you can find your answer there. 10 | 11 | ## How to serialize a message to bytes? 12 | 13 | The easiest way to do it is to invoke `write_to_bytes` function: 14 | 15 | ``` 16 | message.write_to_bytes() 17 | ``` 18 | 19 | ## How to deserialize a message from a byte array? 20 | 21 | ``` 22 | let my_message: MyMessage = protobuf::parse_from_bytes(bytes).unwrap() 23 | ``` 24 | 25 | ## What is `cached_size` field? 26 | 27 | Before serializing protobuf need to know sizes of all nested structures. 28 | 29 | So serialization of protobuf message is done in two steps: 30 | * first, compute sizes of all nested messages 31 | * second, write the message tree with each message prepended by serialized size 32 | 33 | So before serialization protobuf implementation stores size of a message into `cached_size` field. 34 | 35 | (The same strategy used at least in Google's C++ and Java implementation of Protocol Buffers) 36 | 37 | Sometimes it's annoying. Previously rust-protobuf stored message sizes in external buffer, 38 | but it was slightly worse performance-wise. 39 | 40 | rust-protobuf could have an option to skip generation of `cached_size` 41 | and use external buffer when there's no such field. If you need that could be useful to you, 42 | please open an issue. 43 | 44 | ## What is `unknown_fields` field? 45 | 46 | When unknown field is encountered during parsing (e. g. field added in newer version of `.proto` file) 47 | this field data is stored in `unknown_fields`. 48 | The purpose of this field is to be able to perform loseless read-modify-write operation 49 | even with older version of `proto` file which does not know about new fields. 50 | 51 | ## You answer is not there? 52 | 53 | Feel free to open an issue with a question. 54 | -------------------------------------------------------------------------------- /protobuf-test/src/common/v2/test_fmt_text_format_0_pb.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto2"; 2 | 3 | import "rustproto.proto"; 4 | option (rustproto.generate_accessors_all) = true; 5 | 6 | 7 | enum TestEnum { 8 | UNKNOWN = 0; 9 | DARK = 1; 10 | LIGHT = 2; 11 | } 12 | 13 | message TestMessage { 14 | optional int32 value = 10; 15 | } 16 | 17 | message TestTypes { 18 | optional double double_singular = 1; 19 | optional float float_singular = 2; 20 | optional int32 int32_singular = 3; 21 | optional int64 int64_singular = 4; 22 | optional uint32 uint32_singular = 5; 23 | optional uint64 uint64_singular = 6; 24 | optional sint32 sint32_singular = 7; 25 | optional sint64 sint64_singular = 8; 26 | optional fixed32 fixed32_singular = 9; 27 | optional fixed64 fixed64_singular = 10; 28 | optional sfixed32 sfixed32_singular = 11; 29 | optional sfixed64 sfixed64_singular = 12; 30 | optional bool bool_singular = 13; 31 | optional string string_singular = 14; 32 | optional bytes bytes_singular = 15; 33 | optional TestEnum test_enum_singular = 16; 34 | optional TestMessage test_message_singular = 17; 35 | 36 | repeated double double_repeated = 31; 37 | repeated float float_repeated = 32; 38 | repeated int32 int32_repeated = 33; 39 | repeated int64 int64_repeated = 34; 40 | repeated uint32 uint32_repeated = 35; 41 | repeated uint64 uint64_repeated = 36; 42 | repeated sint32 sint32_repeated = 37; 43 | repeated sint64 sint64_repeated = 38; 44 | repeated fixed32 fixed32_repeated = 39; 45 | repeated fixed64 fixed64_repeated = 40; 46 | repeated sfixed32 sfixed32_repeated = 41; 47 | repeated sfixed64 sfixed64_repeated = 42; 48 | repeated bool bool_repeated = 43; 49 | repeated string string_repeated = 44; 50 | repeated bytes bytes_repeated = 45; 51 | repeated TestEnum test_enum_repeated = 46; 52 | repeated TestMessage test_message_repeated = 47; 53 | } 54 | 55 | message TestTextFormatRustIdentifier { 56 | optional bool const = 1; 57 | } 58 | -------------------------------------------------------------------------------- /protobuf-test/src/google/protobuf/unittest_import_public.proto: -------------------------------------------------------------------------------- 1 | // Protocol Buffers - Google's data interchange format 2 | // Copyright 2008 Google Inc. All rights reserved. 3 | // https://developers.google.com/protocol-buffers/ 4 | // 5 | // Redistribution and use in source and binary forms, with or without 6 | // modification, are permitted provided that the following conditions are 7 | // met: 8 | // 9 | // * Redistributions of source code must retain the above copyright 10 | // notice, this list of conditions and the following disclaimer. 11 | // * Redistributions in binary form must reproduce the above 12 | // copyright notice, this list of conditions and the following disclaimer 13 | // in the documentation and/or other materials provided with the 14 | // distribution. 15 | // * Neither the name of Google Inc. nor the names of its 16 | // contributors may be used to endorse or promote products derived from 17 | // this software without specific prior written permission. 18 | // 19 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | 31 | // Author: liujisi@google.com (Pherl Liu) 32 | 33 | syntax = "proto2"; 34 | 35 | package protobuf_unittest_import; 36 | 37 | option java_package = "com.google.protobuf.test"; 38 | 39 | message PublicImportMessage { 40 | optional int32 e = 1; 41 | } 42 | -------------------------------------------------------------------------------- /protobuf-test/src/google/protobuf/unittest_empty.proto: -------------------------------------------------------------------------------- 1 | // Protocol Buffers - Google's data interchange format 2 | // Copyright 2008 Google Inc. All rights reserved. 3 | // https://developers.google.com/protocol-buffers/ 4 | // 5 | // Redistribution and use in source and binary forms, with or without 6 | // modification, are permitted provided that the following conditions are 7 | // met: 8 | // 9 | // * Redistributions of source code must retain the above copyright 10 | // notice, this list of conditions and the following disclaimer. 11 | // * Redistributions in binary form must reproduce the above 12 | // copyright notice, this list of conditions and the following disclaimer 13 | // in the documentation and/or other materials provided with the 14 | // distribution. 15 | // * Neither the name of Google Inc. nor the names of its 16 | // contributors may be used to endorse or promote products derived from 17 | // this software without specific prior written permission. 18 | // 19 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | 31 | // Author: kenton@google.com (Kenton Varda) 32 | // Based on original Protocol Buffers design by 33 | // Sanjay Ghemawat, Jeff Dean, and others. 34 | // 35 | // This file intentionally left blank. (At one point this wouldn't compile 36 | // correctly.) 37 | 38 | syntax = "proto2"; 39 | -------------------------------------------------------------------------------- /protobuf-test/src/google/protobuf/unittest_import_public_lite.proto: -------------------------------------------------------------------------------- 1 | // Protocol Buffers - Google's data interchange format 2 | // Copyright 2008 Google Inc. All rights reserved. 3 | // https://developers.google.com/protocol-buffers/ 4 | // 5 | // Redistribution and use in source and binary forms, with or without 6 | // modification, are permitted provided that the following conditions are 7 | // met: 8 | // 9 | // * Redistributions of source code must retain the above copyright 10 | // notice, this list of conditions and the following disclaimer. 11 | // * Redistributions in binary form must reproduce the above 12 | // copyright notice, this list of conditions and the following disclaimer 13 | // in the documentation and/or other materials provided with the 14 | // distribution. 15 | // * Neither the name of Google Inc. nor the names of its 16 | // contributors may be used to endorse or promote products derived from 17 | // this software without specific prior written permission. 18 | // 19 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | 31 | // Author: liujisi@google.com (Pherl Liu) 32 | 33 | syntax = "proto2"; 34 | 35 | package protobuf_unittest_import; 36 | 37 | option optimize_for = LITE_RUNTIME; 38 | 39 | option java_package = "com.google.protobuf"; 40 | 41 | message PublicImportMessageLite { 42 | optional int32 e = 1; 43 | } 44 | -------------------------------------------------------------------------------- /protobuf/src/varint.rs: -------------------------------------------------------------------------------- 1 | /// Encode u64 as varint. 2 | /// Panics if buffer length is less than 10. 3 | #[inline] 4 | pub fn encode_varint64(mut value: u64, buf: &mut [u8]) -> usize { 5 | assert!(buf.len() >= 10); 6 | 7 | fn iter(value: &mut u64, byte: &mut u8) -> bool { 8 | if (*value & !0x7F) > 0 { 9 | *byte = ((*value & 0x7F) | 0x80) as u8; 10 | *value >>= 7; 11 | true 12 | } else { 13 | *byte = *value as u8; 14 | false 15 | } 16 | } 17 | 18 | // Explicitly unroll loop to avoid either 19 | // unsafe code or bound checking when writing to `buf` 20 | 21 | if !iter(&mut value, &mut buf[0]) { return 1; }; 22 | if !iter(&mut value, &mut buf[1]) { return 2; }; 23 | if !iter(&mut value, &mut buf[2]) { return 3; }; 24 | if !iter(&mut value, &mut buf[3]) { return 4; }; 25 | if !iter(&mut value, &mut buf[4]) { return 5; }; 26 | if !iter(&mut value, &mut buf[5]) { return 6; }; 27 | if !iter(&mut value, &mut buf[6]) { return 7; }; 28 | if !iter(&mut value, &mut buf[7]) { return 8; }; 29 | if !iter(&mut value, &mut buf[8]) { return 9; }; 30 | buf[9] = value as u8; 31 | 10 32 | } 33 | 34 | /// Encode u32 value as varint. 35 | /// Panics if buffer length is less than 5. 36 | #[inline] 37 | pub fn encode_varint32(mut value: u32, buf: &mut [u8]) -> usize { 38 | assert!(buf.len() >= 5); 39 | 40 | fn iter(value: &mut u32, byte: &mut u8) -> bool { 41 | if (*value & !0x7F) > 0 { 42 | *byte = ((*value & 0x7F) | 0x80) as u8; 43 | *value >>= 7; 44 | true 45 | } else { 46 | *byte = *value as u8; 47 | false 48 | } 49 | } 50 | 51 | // Explicitly unroll loop to avoid either 52 | // unsafe code or bound checking when writing to `buf` 53 | 54 | if !iter(&mut value, &mut buf[0]) { return 1; }; 55 | if !iter(&mut value, &mut buf[1]) { return 2; }; 56 | if !iter(&mut value, &mut buf[2]) { return 3; }; 57 | if !iter(&mut value, &mut buf[3]) { return 4; }; 58 | buf[4] = value as u8; 59 | 5 60 | } 61 | -------------------------------------------------------------------------------- /protobuf-test/src/common/v2/test_oneof.rs: -------------------------------------------------------------------------------- 1 | use protobuf_test_common::*; 2 | 3 | use super::test_oneof_pb::*; 4 | 5 | #[test] 6 | fn test_simple() { 7 | let mut test_message = TestOneof::new(); 8 | test_message.set_uint32_field(150); 9 | test_serialize_deserialize("28 96 01", &test_message); 10 | } 11 | 12 | #[test] 13 | fn test_set_clear_field() { 14 | let mut test_message = TestOneof::new(); 15 | 16 | test_message.set_int32_field(10); 17 | assert!(test_message.has_int32_field()); 18 | assert_eq!(10, test_message.get_int32_field()); 19 | assert!(!test_message.has_bool_field()); 20 | assert_eq!(false, test_message.get_bool_field()); 21 | 22 | test_message.set_bool_field(true); 23 | assert!(test_message.has_bool_field()); 24 | assert_eq!(true, test_message.get_bool_field()); 25 | assert!(!test_message.has_int32_field()); 26 | assert_eq!(0, test_message.get_int32_field()); 27 | 28 | test_message.clear_int32_field(); 29 | assert!(!test_message.has_int32_field()); 30 | assert!(!test_message.has_bool_field()); 31 | assert_eq!(false, test_message.get_bool_field()); 32 | assert_eq!(0, test_message.get_int32_field()); 33 | } 34 | 35 | #[test] 36 | fn test_types() { 37 | fn t(f: F) 38 | where 39 | F: Fn(&mut TestOneof), 40 | { 41 | let mut o = TestOneof::new(); 42 | f(&mut o); 43 | test_serialize_deserialize_no_hex(&o); 44 | } 45 | 46 | t(|o| o.set_double_field(10.0)); 47 | t(|o| o.set_float_field(11.0)); 48 | t(|o| o.set_int32_field(12)); 49 | t(|o| o.set_int64_field(13)); 50 | t(|o| o.set_uint32_field(14)); 51 | t(|o| o.set_uint64_field(15)); 52 | t(|o| o.set_sint32_field(16)); 53 | t(|o| o.set_sint64_field(17)); 54 | t(|o| o.set_fixed32_field(18)); 55 | t(|o| o.set_fixed64_field(19)); 56 | t(|o| o.set_sfixed32_field(20)); 57 | t(|o| o.set_sfixed64_field(21)); 58 | t(|o| o.set_bool_field(true)); 59 | t(|o| o.set_string_field("asas".to_string())); 60 | t(|o| o.set_bytes_field(vec![99, 100])); 61 | t(|o| o.set_enum_field(EnumForOneof::A)); 62 | t(|o| o.mut_message_field().set_f(22)); 63 | } 64 | -------------------------------------------------------------------------------- /protobuf-test/src/v2/test_default_values_pb.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto2"; 2 | 3 | package test_default_values; 4 | 5 | enum EnumForDefaultValue { 6 | ONE = 1; 7 | TWO = 2; 8 | THREE = 3; 9 | } 10 | 11 | message TestDefaultValues { 12 | optional double double_field = 1 [default = 1]; 13 | optional float float_field = 2 [default = 2]; 14 | 15 | optional int32 int32_field = 3 [default = 3]; 16 | optional int64 int64_field = 4 [default = 4]; 17 | optional uint32 uint32_field = 5 [default = 5]; 18 | optional uint64 uint64_field = 6 [default = 6]; 19 | optional sint32 sint32_field = 7 [default = 7]; 20 | optional sint64 sint64_field = 8 [default = 8]; 21 | optional fixed32 fixed32_field = 9 [default = 9]; 22 | optional fixed64 fixed64_field = 10 [default = 10]; 23 | optional sfixed32 sfixed32_field = 11 [default = 11]; 24 | optional sfixed64 sfixed64_field = 12 [default = 12]; 25 | optional bool bool_field = 13 [default = true]; 26 | optional string string_field = 14 [default = "abc\n22"]; 27 | optional bytes bytes_field = 15 [default = "cde\n33"]; 28 | optional EnumForDefaultValue enum_field = 16 [default = TWO]; 29 | optional EnumForDefaultValue enum_field_without_default = 17; 30 | } 31 | 32 | message TestExtremeDefaultValues { 33 | // Text for nonfinite floating-point values. 34 | optional bytes escaped_bytes = 1 [default = "\0\001\a\b\f\n\r\t\v\\\'\"\xfe"]; 35 | optional string quote1 = 111 [default = "'"]; 36 | optional string quote2 = 112 [default = '"']; 37 | optional bytes bquote1 = 211 [default = "'"]; 38 | optional bytes bquote2 = 212 [default = '"']; 39 | optional double inf_double = 14 [default = inf]; 40 | optional double neg_inf_double = 15 [default = -inf]; 41 | optional double nan_double = 16 [default = nan]; 42 | optional float inf_float = 17 [default = inf]; 43 | optional float neg_inf_float = 18 [default = -inf]; 44 | optional float nan_float = 19 [default = nan]; 45 | } 46 | -------------------------------------------------------------------------------- /protobuf-test/src/google/protobuf/unittest_lite_imports_nonlite.proto: -------------------------------------------------------------------------------- 1 | // Protocol Buffers - Google's data interchange format 2 | // Copyright 2008 Google Inc. All rights reserved. 3 | // https://developers.google.com/protocol-buffers/ 4 | // 5 | // Redistribution and use in source and binary forms, with or without 6 | // modification, are permitted provided that the following conditions are 7 | // met: 8 | // 9 | // * Redistributions of source code must retain the above copyright 10 | // notice, this list of conditions and the following disclaimer. 11 | // * Redistributions in binary form must reproduce the above 12 | // copyright notice, this list of conditions and the following disclaimer 13 | // in the documentation and/or other materials provided with the 14 | // distribution. 15 | // * Neither the name of Google Inc. nor the names of its 16 | // contributors may be used to endorse or promote products derived from 17 | // this software without specific prior written permission. 18 | // 19 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | 31 | // Author: kenton@google.com (Kenton Varda) 32 | // 33 | // Tests that a "lite" message can import a regular message. 34 | 35 | syntax = "proto2"; 36 | package protobuf_unittest; 37 | 38 | import "google/protobuf/unittest.proto"; 39 | 40 | option optimize_for = LITE_RUNTIME; 41 | 42 | message TestLiteImportsNonlite { 43 | optional TestAllTypes message = 1; 44 | } 45 | -------------------------------------------------------------------------------- /protobuf-test/src/common/v2/test_map_simple.rs: -------------------------------------------------------------------------------- 1 | use protobuf::text_format::print_to_string; 2 | 3 | use super::test_map_simple_pb::*; 4 | 5 | use protobuf_test_common::*; 6 | 7 | #[test] 8 | fn test_map() { 9 | let mut map = TestMap::new(); 10 | let mut entry = TestMapEntry::new(); 11 | entry.set_v(10); 12 | 13 | test_serialize_deserialize("", &map); 14 | 15 | map.mut_m().insert("two".to_owned(), 2); 16 | test_serialize_deserialize("0a 07 0a 03 74 77 6f 10 02", &map); 17 | 18 | map.mut_m().insert("sixty six".to_owned(), 66); 19 | // Insert map entry sub message 20 | map.mut_mm().insert("map".to_owned(), entry); 21 | // cannot (easily) test hex, because order is not specified 22 | test_serialize_deserialize_no_hex(&map); 23 | } 24 | 25 | #[test] 26 | fn test_map_negative_i32_value() { 27 | let mut map = TestMap::new(); 28 | map.mut_m().insert("two".to_owned(), -2); 29 | test_serialize_deserialize("0a 10 0a 03 74 77 6f 10 fe ff ff ff ff ff ff ff ff 01", &map); 30 | } 31 | 32 | #[test] 33 | fn test_map_with_object() { 34 | let mut map = TestMap::new(); 35 | 36 | let mut entry = TestMapEntry::new(); 37 | entry.set_v(10); 38 | 39 | test_serialize_deserialize("", &map); 40 | 41 | map.mut_mm().insert("map".to_owned(), entry); 42 | // cannot (easily) test hex, because order is not specified 43 | test_serialize_deserialize_no_hex(&map); 44 | } 45 | 46 | #[test] 47 | fn test_map_unset_default_fields() { 48 | // unset key and value 49 | let mut m = TestMap::new(); 50 | m.m.insert("".to_owned(), 0); 51 | test_deserialize("0a 00", &m); 52 | 53 | // unset value 54 | let mut m = TestMap::new(); 55 | m.m.insert("ab".to_owned(), 0); 56 | test_deserialize("0a 04 0a 02 61 62", &m); 57 | 58 | // unset key 59 | let mut m = TestMap::new(); 60 | m.m.insert("".to_owned(), 17); 61 | test_deserialize("0a 02 10 11", &m); 62 | } 63 | 64 | #[test] 65 | fn text_format() { 66 | let mut map = TestMap::new(); 67 | 68 | assert_eq!(&*print_to_string(&map), ""); 69 | 70 | map.mut_m().insert("two".to_owned(), 2); 71 | 72 | assert_eq!(&*print_to_string(&map), "m {key: \"two\" value: 2}") 73 | } 74 | -------------------------------------------------------------------------------- /protobuf-test/src/google/protobuf/unittest_arena.proto: -------------------------------------------------------------------------------- 1 | // Protocol Buffers - Google's data interchange format 2 | // Copyright 2008 Google Inc. All rights reserved. 3 | // https://developers.google.com/protocol-buffers/ 4 | // 5 | // Redistribution and use in source and binary forms, with or without 6 | // modification, are permitted provided that the following conditions are 7 | // met: 8 | // 9 | // * Redistributions of source code must retain the above copyright 10 | // notice, this list of conditions and the following disclaimer. 11 | // * Redistributions in binary form must reproduce the above 12 | // copyright notice, this list of conditions and the following disclaimer 13 | // in the documentation and/or other materials provided with the 14 | // distribution. 15 | // * Neither the name of Google Inc. nor the names of its 16 | // contributors may be used to endorse or promote products derived from 17 | // this software without specific prior written permission. 18 | // 19 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | 31 | syntax = "proto2"; 32 | 33 | import "google/protobuf/unittest_no_arena_import.proto"; 34 | 35 | package proto2_arena_unittest; 36 | 37 | option cc_enable_arenas = true; 38 | 39 | message NestedMessage { 40 | optional int32 d = 1; 41 | } 42 | 43 | message ArenaMessage { 44 | repeated NestedMessage repeated_nested_message = 1; 45 | repeated ImportNoArenaNestedMessage repeated_import_no_arena_message = 2; 46 | }; 47 | -------------------------------------------------------------------------------- /protobuf-test/src/google/protobuf/unittest_no_arena_lite.proto: -------------------------------------------------------------------------------- 1 | // Protocol Buffers - Google's data interchange format 2 | // Copyright 2008 Google Inc. All rights reserved. 3 | // https://developers.google.com/protocol-buffers/ 4 | // 5 | // Redistribution and use in source and binary forms, with or without 6 | // modification, are permitted provided that the following conditions are 7 | // met: 8 | // 9 | // * Redistributions of source code must retain the above copyright 10 | // notice, this list of conditions and the following disclaimer. 11 | // * Redistributions in binary form must reproduce the above 12 | // copyright notice, this list of conditions and the following disclaimer 13 | // in the documentation and/or other materials provided with the 14 | // distribution. 15 | // * Neither the name of Google Inc. nor the names of its 16 | // contributors may be used to endorse or promote products derived from 17 | // this software without specific prior written permission. 18 | // 19 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | 31 | syntax = "proto2"; 32 | 33 | option optimize_for = LITE_RUNTIME; 34 | 35 | // We don't put this in a package within proto2 because we need to make sure 36 | // that the generated code doesn't depend on being in the proto2 namespace. 37 | // In test_util.h we do "using namespace unittest = protobuf_unittest". 38 | package protobuf_unittest_no_arena; 39 | 40 | message ForeignMessageLite { 41 | optional int32 c = 1; 42 | } 43 | -------------------------------------------------------------------------------- /protobuf/src/reflect/transmute_eq.rs: -------------------------------------------------------------------------------- 1 | #[cfg(not(rustc_nightly))] 2 | mod transmute_eq_impl { 3 | use std::any::Any; 4 | use std::mem; 5 | 6 | #[inline(always)] 7 | pub fn transmute_eq(mut from: F) -> Result { 8 | // call downcast twice to work around borrow checked 9 | if (&mut from as &mut Any).downcast_mut::().is_none() { 10 | return Err(from); 11 | } 12 | 13 | let to = unsafe { 14 | let from_as_to = (&mut from as &mut Any).downcast_mut().unwrap(); 15 | let mut to = mem::uninitialized(); 16 | mem::swap(from_as_to, &mut to); 17 | to 18 | }; 19 | mem::forget(from); 20 | Ok(to) 21 | } 22 | 23 | } 24 | 25 | #[cfg(rustc_nightly)] 26 | mod transmute_eq_impl { 27 | use std::marker; 28 | 29 | trait TransmuteEq { 30 | fn transmute_eq(from: From) -> Result; 31 | } 32 | 33 | struct TransmuteEqImpl(marker::PhantomData<(F, T)>); 34 | 35 | impl TransmuteEq for TransmuteEqImpl { 36 | #[inline(always)] 37 | default fn transmute_eq(from: F) -> Result { 38 | Err(from) 39 | } 40 | } 41 | 42 | impl TransmuteEq for TransmuteEqImpl { 43 | #[inline(always)] 44 | fn transmute_eq(from: S) -> Result { 45 | Ok(from) 46 | } 47 | } 48 | 49 | #[inline(always)] 50 | pub fn transmute_eq(from: F) -> Result { 51 | TransmuteEqImpl::::transmute_eq(from) 52 | } 53 | } 54 | 55 | /// Check if types `F` and `T` are the same. 56 | #[inline(always)] 57 | pub fn transmute_eq(from: F) -> Result { 58 | transmute_eq_impl::transmute_eq(from) 59 | } 60 | 61 | #[cfg(test)] 62 | mod test { 63 | use super::*; 64 | 65 | #[test] 66 | fn test_ok() { 67 | assert_eq!( 68 | Ok("ab".to_owned()), 69 | transmute_eq::("ab".to_owned()) 70 | ) 71 | } 72 | 73 | #[test] 74 | fn test_err() { 75 | assert_eq!( 76 | Err("ab".to_owned()), 77 | transmute_eq::>("ab".to_owned()) 78 | ) 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /protobuf-test/src/google/protobuf/unittest_preserve_unknown_enum2.proto: -------------------------------------------------------------------------------- 1 | // Protocol Buffers - Google's data interchange format 2 | // Copyright 2008 Google Inc. All rights reserved. 3 | // https://developers.google.com/protocol-buffers/ 4 | // 5 | // Redistribution and use in source and binary forms, with or without 6 | // modification, are permitted provided that the following conditions are 7 | // met: 8 | // 9 | // * Redistributions of source code must retain the above copyright 10 | // notice, this list of conditions and the following disclaimer. 11 | // * Redistributions in binary form must reproduce the above 12 | // copyright notice, this list of conditions and the following disclaimer 13 | // in the documentation and/or other materials provided with the 14 | // distribution. 15 | // * Neither the name of Google Inc. nor the names of its 16 | // contributors may be used to endorse or promote products derived from 17 | // this software without specific prior written permission. 18 | // 19 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | 31 | syntax = "proto2"; 32 | 33 | package proto2_preserve_unknown_enum_unittest; 34 | 35 | enum MyEnum { 36 | FOO = 0; 37 | BAR = 1; 38 | BAZ = 2; 39 | } 40 | 41 | message MyMessage { 42 | optional MyEnum e = 1; 43 | repeated MyEnum repeated_e = 2; 44 | repeated MyEnum repeated_packed_e = 3 [packed=true]; 45 | repeated MyEnum repeated_packed_unexpected_e = 4; // not packed 46 | oneof o { 47 | MyEnum oneof_e_1 = 5; 48 | MyEnum oneof_e_2 = 6; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /protobuf-test/src/google/protobuf/unittest_no_generic_services.proto: -------------------------------------------------------------------------------- 1 | // Protocol Buffers - Google's data interchange format 2 | // Copyright 2008 Google Inc. All rights reserved. 3 | // https://developers.google.com/protocol-buffers/ 4 | // 5 | // Redistribution and use in source and binary forms, with or without 6 | // modification, are permitted provided that the following conditions are 7 | // met: 8 | // 9 | // * Redistributions of source code must retain the above copyright 10 | // notice, this list of conditions and the following disclaimer. 11 | // * Redistributions in binary form must reproduce the above 12 | // copyright notice, this list of conditions and the following disclaimer 13 | // in the documentation and/or other materials provided with the 14 | // distribution. 15 | // * Neither the name of Google Inc. nor the names of its 16 | // contributors may be used to endorse or promote products derived from 17 | // this software without specific prior written permission. 18 | // 19 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | 31 | // Author: kenton@google.com (Kenton Varda) 32 | 33 | syntax = "proto2"; 34 | package google.protobuf.no_generic_services_test; 35 | 36 | 37 | // *_generic_services are false by default. 38 | 39 | message TestMessage { 40 | optional int32 a = 1; 41 | extensions 1000 to max; 42 | } 43 | 44 | enum TestEnum { 45 | FOO = 1; 46 | } 47 | 48 | extend TestMessage { 49 | optional int32 test_extension = 1000; 50 | } 51 | 52 | service TestService { 53 | rpc Foo(TestMessage) returns(TestMessage); 54 | } 55 | -------------------------------------------------------------------------------- /protobuf-test/src/google/protobuf/unittest_import_lite.proto: -------------------------------------------------------------------------------- 1 | // Protocol Buffers - Google's data interchange format 2 | // Copyright 2008 Google Inc. All rights reserved. 3 | // https://developers.google.com/protocol-buffers/ 4 | // 5 | // Redistribution and use in source and binary forms, with or without 6 | // modification, are permitted provided that the following conditions are 7 | // met: 8 | // 9 | // * Redistributions of source code must retain the above copyright 10 | // notice, this list of conditions and the following disclaimer. 11 | // * Redistributions in binary form must reproduce the above 12 | // copyright notice, this list of conditions and the following disclaimer 13 | // in the documentation and/or other materials provided with the 14 | // distribution. 15 | // * Neither the name of Google Inc. nor the names of its 16 | // contributors may be used to endorse or promote products derived from 17 | // this software without specific prior written permission. 18 | // 19 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | 31 | // Author: kenton@google.com (Kenton Varda) 32 | // 33 | // This is like unittest_import.proto but with optimize_for = LITE_RUNTIME. 34 | 35 | syntax = "proto2"; 36 | package protobuf_unittest_import; 37 | 38 | option optimize_for = LITE_RUNTIME; 39 | 40 | option java_package = "com.google.protobuf"; 41 | 42 | import public "google/protobuf/unittest_import_public_lite.proto"; 43 | 44 | message ImportMessageLite { 45 | optional int32 d = 1; 46 | } 47 | 48 | enum ImportEnumLite { 49 | IMPORT_LITE_FOO = 7; 50 | IMPORT_LITE_BAR = 8; 51 | IMPORT_LITE_BAZ = 9; 52 | } 53 | -------------------------------------------------------------------------------- /protobuf/src/reflect/runtime_type_dynamic.rs: -------------------------------------------------------------------------------- 1 | use std::marker; 2 | use std::any::TypeId; 3 | use std::any::Any; 4 | 5 | use crate::reflect::runtime_type_box::RuntimeTypeBox; 6 | use crate::reflect::runtime_types::RuntimeType; 7 | use crate::reflect::EnumDescriptor; 8 | use crate::reflect::MessageDescriptor; 9 | use crate::reflect::ProtobufValue; 10 | use crate::reflect::ReflectValueRef; 11 | 12 | 13 | /// Dynamic version of `RuntimeType`. 14 | /// 15 | /// This is used internally in reflection implementation. 16 | pub trait RuntimeTypeDynamic: Send + Sync + 'static { 17 | /// Convert to "enum" version 18 | fn to_box(&self) -> RuntimeTypeBox; 19 | 20 | /// Convert a value reference to `ReflectValueRef` object. 21 | /// 22 | /// # Panics 23 | /// 24 | /// If value type does not match this type object 25 | fn value_to_ref<'a>(&self, value: &'a dyn ProtobufValue) -> ReflectValueRef<'a>; 26 | 27 | /// Default value for type 28 | fn default_value_ref(&self) -> ReflectValueRef; 29 | 30 | /// `EnumDescriptor` for this type. 31 | /// 32 | /// # Panics 33 | /// 34 | /// If this type is not enum. 35 | fn enum_descriptor(&self) -> &'static EnumDescriptor; 36 | 37 | /// `MessageDescriptor` for this type. 38 | /// 39 | /// # Panics 40 | /// 41 | /// If this type is not message. 42 | fn message_descriptor(&self) -> &'static MessageDescriptor; 43 | } 44 | 45 | pub(crate) struct RuntimeTypeDynamicImpl(pub marker::PhantomData); 46 | 47 | impl RuntimeTypeDynamic for RuntimeTypeDynamicImpl { 48 | fn to_box(&self) -> RuntimeTypeBox { 49 | T::runtime_type_box() 50 | } 51 | 52 | fn value_to_ref<'a>(&self, value: &'a dyn ProtobufValue) -> ReflectValueRef<'a> { 53 | if Any::type_id(value) == TypeId::of::() { 54 | unsafe { 55 | T::as_ref(&*(value as *const dyn ProtobufValue as *const T::Value)) 56 | } 57 | } else { 58 | panic!("wrong type") 59 | } 60 | } 61 | 62 | fn default_value_ref(&self) -> ReflectValueRef { 63 | T::default_value_ref() 64 | } 65 | 66 | fn enum_descriptor(&self) -> &'static EnumDescriptor { 67 | T::enum_descriptor() 68 | } 69 | fn message_descriptor(&self) -> &'static MessageDescriptor { 70 | T::message_descriptor() 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /protobuf-test-common/src/hex.rs: -------------------------------------------------------------------------------- 1 | // hex encoder and decoder used by rust-protobuf unittests 2 | 3 | use std::char; 4 | 5 | fn decode_hex_digit(digit: char) -> u8 { 6 | match digit { 7 | '0'...'9' => digit as u8 - '0' as u8, 8 | 'a'...'f' => digit as u8 - 'a' as u8 + 10, 9 | 'A'...'F' => digit as u8 - 'A' as u8 + 10, 10 | _ => panic!(), 11 | } 12 | } 13 | 14 | pub fn decode_hex(hex: &str) -> Vec { 15 | let mut r: Vec = Vec::new(); 16 | let mut chars = hex.chars().enumerate(); 17 | loop { 18 | let (pos, first) = match chars.next() { 19 | None => break, 20 | Some(elt) => elt, 21 | }; 22 | if first == ' ' { 23 | continue; 24 | } 25 | let (_, second) = match chars.next() { 26 | None => panic!("pos = {}d", pos), 27 | Some(elt) => elt, 28 | }; 29 | r.push((decode_hex_digit(first) << 4) | decode_hex_digit(second)); 30 | } 31 | r 32 | } 33 | 34 | fn encode_hex_digit(digit: u8) -> char { 35 | match char::from_digit(digit as u32, 16) { 36 | Some(c) => c, 37 | _ => panic!(), 38 | } 39 | } 40 | 41 | fn encode_hex_byte(byte: u8) -> [char; 2] { 42 | [encode_hex_digit(byte >> 4), encode_hex_digit(byte & 0x0Fu8)] 43 | } 44 | 45 | pub fn encode_hex(bytes: &[u8]) -> String { 46 | let strs: Vec = bytes 47 | .iter() 48 | .map(|byte| encode_hex_byte(*byte).iter().map(|c| *c).collect()) 49 | .collect(); 50 | strs.join(" ") 51 | } 52 | 53 | #[cfg(test)] 54 | mod test { 55 | 56 | use super::decode_hex; 57 | use super::encode_hex; 58 | 59 | #[test] 60 | fn test_decode_hex() { 61 | assert_eq!(decode_hex(""), [].to_vec()); 62 | assert_eq!(decode_hex("00"), [0x00u8].to_vec()); 63 | assert_eq!(decode_hex("ff"), [0xffu8].to_vec()); 64 | assert_eq!(decode_hex("AB"), [0xabu8].to_vec()); 65 | assert_eq!(decode_hex("fa 19"), [0xfau8, 0x19].to_vec()); 66 | } 67 | 68 | #[test] 69 | fn test_encode_hex() { 70 | assert_eq!("".to_string(), encode_hex(&[])); 71 | assert_eq!("00".to_string(), encode_hex(&[0x00])); 72 | assert_eq!("ab".to_string(), encode_hex(&[0xab])); 73 | assert_eq!( 74 | "01 a2 1a fe".to_string(), 75 | encode_hex(&[0x01, 0xa2, 0x1a, 0xfe]) 76 | ); 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /protobuf-test/src/google/protobuf/unittest_drop_unknown_fields.proto: -------------------------------------------------------------------------------- 1 | // Protocol Buffers - Google's data interchange format 2 | // Copyright 2008 Google Inc. All rights reserved. 3 | // https://developers.google.com/protocol-buffers/ 4 | // 5 | // Redistribution and use in source and binary forms, with or without 6 | // modification, are permitted provided that the following conditions are 7 | // met: 8 | // 9 | // * Redistributions of source code must retain the above copyright 10 | // notice, this list of conditions and the following disclaimer. 11 | // * Redistributions in binary form must reproduce the above 12 | // copyright notice, this list of conditions and the following disclaimer 13 | // in the documentation and/or other materials provided with the 14 | // distribution. 15 | // * Neither the name of Google Inc. nor the names of its 16 | // contributors may be used to endorse or promote products derived from 17 | // this software without specific prior written permission. 18 | // 19 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | 31 | syntax = "proto3"; 32 | 33 | package unittest_drop_unknown_fields; 34 | option objc_class_prefix = "DropUnknowns"; 35 | 36 | option csharp_namespace = "Google.Protobuf.TestProtos"; 37 | 38 | message Foo { 39 | enum NestedEnum { 40 | FOO = 0; 41 | BAR = 1; 42 | BAZ = 2; 43 | } 44 | int32 int32_value = 1; 45 | NestedEnum enum_value = 2; 46 | } 47 | 48 | message FooWithExtraFields { 49 | enum NestedEnum { 50 | FOO = 0; 51 | BAR = 1; 52 | BAZ = 2; 53 | QUX = 3; 54 | } 55 | int32 int32_value = 1; 56 | NestedEnum enum_value = 2; 57 | int32 extra_int32_value = 3; 58 | } 59 | -------------------------------------------------------------------------------- /proto/google/protobuf/source_context.proto: -------------------------------------------------------------------------------- 1 | // Protocol Buffers - Google's data interchange format 2 | // Copyright 2008 Google Inc. All rights reserved. 3 | // https://developers.google.com/protocol-buffers/ 4 | // 5 | // Redistribution and use in source and binary forms, with or without 6 | // modification, are permitted provided that the following conditions are 7 | // met: 8 | // 9 | // * Redistributions of source code must retain the above copyright 10 | // notice, this list of conditions and the following disclaimer. 11 | // * Redistributions in binary form must reproduce the above 12 | // copyright notice, this list of conditions and the following disclaimer 13 | // in the documentation and/or other materials provided with the 14 | // distribution. 15 | // * Neither the name of Google Inc. nor the names of its 16 | // contributors may be used to endorse or promote products derived from 17 | // this software without specific prior written permission. 18 | // 19 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | 31 | syntax = "proto3"; 32 | 33 | package google.protobuf; 34 | 35 | option csharp_namespace = "Google.Protobuf.WellKnownTypes"; 36 | option java_package = "com.google.protobuf"; 37 | option java_outer_classname = "SourceContextProto"; 38 | option java_multiple_files = true; 39 | option objc_class_prefix = "GPB"; 40 | 41 | // `SourceContext` represents information about the source of a 42 | // protobuf element, like the file in which it is defined. 43 | message SourceContext { 44 | // The path-qualified name of the .proto file that contained the associated 45 | // protobuf element. For example: `"google/protobuf/source_context.proto"`. 46 | string file_name = 1; 47 | } 48 | -------------------------------------------------------------------------------- /protobuf-fuzz/src/all_types_pb.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | message EmptyMessage {} 4 | 5 | 6 | message SubM { 7 | int32 n = 1; 8 | } 9 | 10 | enum TestEnum { 11 | UNDEFINED = 0; 12 | RED = 1; 13 | BLUE = 2; 14 | GREEN = 3; 15 | } 16 | 17 | message TestTypesSingular { 18 | double double_field = 1; 19 | float float_field = 2; 20 | int32 int32_field = 3; 21 | int64 int64_field = 4; 22 | uint32 uint32_field = 5; 23 | uint64 uint64_field = 6; 24 | sint32 sint32_field = 7; 25 | sint64 sint64_field = 8; 26 | fixed32 fixed32_field = 9; 27 | fixed64 fixed64_field = 10; 28 | sfixed32 sfixed32_field = 11; 29 | sfixed64 sfixed64_field = 12; 30 | bool bool_field = 13; 31 | string string_field = 14; 32 | bytes bytes_field = 15; 33 | TestEnum enum_field = 16; 34 | SubM message_field = 17; 35 | } 36 | 37 | message TestTypesRepeated { 38 | repeated double double_field = 1; 39 | repeated float float_field = 2; 40 | repeated int32 int32_field = 3; 41 | repeated int64 int64_field = 4; 42 | repeated uint32 uint32_field = 5; 43 | repeated uint64 uint64_field = 6; 44 | repeated sint32 sint32_field = 7; 45 | repeated sint64 sint64_field = 8; 46 | repeated fixed32 fixed32_field = 9; 47 | repeated fixed64 fixed64_field = 10; 48 | repeated sfixed32 sfixed32_field = 11; 49 | repeated sfixed64 sfixed64_field = 12; 50 | repeated bool bool_field = 13; 51 | repeated string string_field = 14; 52 | repeated bytes bytes_field = 15; 53 | repeated TestEnum enum_field = 16; 54 | repeated SubM message_field = 17; 55 | } 56 | 57 | // All possibe key and value types 58 | message TestTypesMap { 59 | map double_field = 1; 60 | map float_field = 2; 61 | map int32_field = 3; 62 | map int64_field = 4; 63 | map uint32_field = 5; 64 | map uint64_field = 6; 65 | map sint32_field = 7; 66 | map sint64_field = 8; 67 | map fixed32_field = 9; 68 | map fixed64_field = 10; 69 | map sfixed32_field = 11; 70 | map sfixed64_field = 12; 71 | map bool_field = 13; 72 | map string_field = 14; 73 | map bytes_field = 15; 74 | map enum_field = 16; 75 | map message_field = 17; 76 | } 77 | -------------------------------------------------------------------------------- /protobuf/src/lib.rs: -------------------------------------------------------------------------------- 1 | //! Library to read and write protocol buffers data. 2 | 3 | #![deny(missing_docs)] 4 | #![deny(intra_doc_link_resolution_failure)] 5 | 6 | #![cfg_attr(rustc_nightly, feature(specialization))] 7 | 8 | #[cfg(feature = "bytes")] 9 | extern crate bytes; 10 | #[cfg(feature = "with-serde")] 11 | extern crate serde; 12 | #[macro_use] 13 | #[cfg(feature = "with-serde")] 14 | 15 | extern crate serde_derive; 16 | pub use crate::clear::Clear; 17 | pub use crate::core::parse_from_bytes; 18 | #[cfg(feature = "bytes")] 19 | pub use crate::core::parse_from_carllerche_bytes; 20 | pub use crate::core::parse_from_reader; 21 | pub use crate::core::Message; 22 | pub use crate::enums::ProtobufEnum; 23 | pub use crate::enums::ProtobufEnumOrUnknown; 24 | pub use crate::oneof::Oneof; 25 | pub use crate::repeated::RepeatedField; 26 | pub use crate::singular::SingularField; 27 | pub use crate::singular::SingularPtrField; 28 | pub use crate::stream::CodedInputStream; 29 | pub use crate::stream::CodedOutputStream; 30 | pub use crate::unknown::UnknownFields; 31 | pub use crate::unknown::UnknownFieldsIter; 32 | pub use crate::unknown::UnknownValue; 33 | pub use crate::unknown::UnknownValueRef; 34 | pub use crate::unknown::UnknownValues; 35 | pub use crate::unknown::UnknownValuesIter; 36 | pub mod wire_format; 37 | #[cfg(feature = "bytes")] 38 | pub use crate::chars::Chars; 39 | pub use crate::error::ProtobufError; 40 | pub use crate::error::ProtobufResult; 41 | 42 | // generated 43 | pub mod descriptor; 44 | // TODO: move plugin to mod codegen 45 | pub mod plugin; 46 | pub mod rustproto; 47 | 48 | mod clear; 49 | mod core; 50 | mod enums; 51 | mod error; 52 | pub mod ext; 53 | pub mod json; 54 | mod lazy; 55 | mod oneof; 56 | pub mod prelude; 57 | pub mod reflect; 58 | mod repeated; 59 | pub mod rt; 60 | mod singular; 61 | mod stream; 62 | pub mod text_format; 63 | pub mod well_known_types; 64 | 65 | // used by test 66 | #[cfg(test)] 67 | #[path = "../../protobuf-test-common/src/hex.rs"] 68 | mod hex; 69 | 70 | mod cached_size; 71 | mod chars; 72 | mod paginate; 73 | mod unknown; 74 | mod varint; 75 | mod zigzag; 76 | 77 | mod misc; 78 | 79 | mod buf_read_iter; 80 | mod buf_read_or_reader; 81 | 82 | /// This symbol is in generated `version.rs`, include here for IDE 83 | #[cfg(never)] 84 | pub const VERSION: &str = ""; 85 | /// This symbol is in generated `version.rs`, include here for IDE 86 | #[cfg(never)] 87 | #[doc(hidden)] 88 | pub const VERSION_IDENT: &str = ""; 89 | include!(concat!(env!("OUT_DIR"), "/version.rs")); 90 | -------------------------------------------------------------------------------- /protobuf-test/src/google/protobuf/unittest_mset_wire_format.proto: -------------------------------------------------------------------------------- 1 | // Protocol Buffers - Google's data interchange format 2 | // Copyright 2008 Google Inc. All rights reserved. 3 | // https://developers.google.com/protocol-buffers/ 4 | // 5 | // Redistribution and use in source and binary forms, with or without 6 | // modification, are permitted provided that the following conditions are 7 | // met: 8 | // 9 | // * Redistributions of source code must retain the above copyright 10 | // notice, this list of conditions and the following disclaimer. 11 | // * Redistributions in binary form must reproduce the above 12 | // copyright notice, this list of conditions and the following disclaimer 13 | // in the documentation and/or other materials provided with the 14 | // distribution. 15 | // * Neither the name of Google Inc. nor the names of its 16 | // contributors may be used to endorse or promote products derived from 17 | // this software without specific prior written permission. 18 | // 19 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | 31 | // Author: kenton@google.com (Kenton Varda) 32 | // Based on original Protocol Buffers design by 33 | // Sanjay Ghemawat, Jeff Dean, and others. 34 | // 35 | // This file contains messages for testing message_set_wire_format. 36 | 37 | syntax = "proto2"; 38 | package proto2_wireformat_unittest; 39 | 40 | option cc_enable_arenas = true; 41 | option optimize_for = SPEED; 42 | option csharp_namespace = "Google.ProtocolBuffers.TestProtos"; 43 | 44 | // A message with message_set_wire_format. 45 | message TestMessageSet { 46 | option message_set_wire_format = true; 47 | extensions 4 to max; 48 | } 49 | 50 | message TestMessageSetWireFormatContainer { 51 | optional TestMessageSet message_set = 1; 52 | } 53 | -------------------------------------------------------------------------------- /protobuf-test/src/google/protobuf/unittest_embed_optimize_for.proto: -------------------------------------------------------------------------------- 1 | // Protocol Buffers - Google's data interchange format 2 | // Copyright 2008 Google Inc. All rights reserved. 3 | // https://developers.google.com/protocol-buffers/ 4 | // 5 | // Redistribution and use in source and binary forms, with or without 6 | // modification, are permitted provided that the following conditions are 7 | // met: 8 | // 9 | // * Redistributions of source code must retain the above copyright 10 | // notice, this list of conditions and the following disclaimer. 11 | // * Redistributions in binary form must reproduce the above 12 | // copyright notice, this list of conditions and the following disclaimer 13 | // in the documentation and/or other materials provided with the 14 | // distribution. 15 | // * Neither the name of Google Inc. nor the names of its 16 | // contributors may be used to endorse or promote products derived from 17 | // this software without specific prior written permission. 18 | // 19 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | 31 | // Author: kenton@google.com (Kenton Varda) 32 | // Based on original Protocol Buffers design by 33 | // Sanjay Ghemawat, Jeff Dean, and others. 34 | // 35 | // A proto file which imports a proto file that uses optimize_for = CODE_SIZE. 36 | 37 | syntax = "proto2"; 38 | import "google/protobuf/unittest_optimize_for.proto"; 39 | 40 | package protobuf_unittest; 41 | 42 | // We optimize for speed here, but we are importing a proto that is optimized 43 | // for code size. 44 | option optimize_for = SPEED; 45 | 46 | message TestEmbedOptimizedForSize { 47 | // Test that embedding a message which has optimize_for = CODE_SIZE into 48 | // one optimized for speed works. 49 | optional TestOptimizedForSize optional_message = 1; 50 | repeated TestOptimizedForSize repeated_message = 2; 51 | } 52 | -------------------------------------------------------------------------------- /proto/google/protobuf/empty.proto: -------------------------------------------------------------------------------- 1 | // Protocol Buffers - Google's data interchange format 2 | // Copyright 2008 Google Inc. All rights reserved. 3 | // https://developers.google.com/protocol-buffers/ 4 | // 5 | // Redistribution and use in source and binary forms, with or without 6 | // modification, are permitted provided that the following conditions are 7 | // met: 8 | // 9 | // * Redistributions of source code must retain the above copyright 10 | // notice, this list of conditions and the following disclaimer. 11 | // * Redistributions in binary form must reproduce the above 12 | // copyright notice, this list of conditions and the following disclaimer 13 | // in the documentation and/or other materials provided with the 14 | // distribution. 15 | // * Neither the name of Google Inc. nor the names of its 16 | // contributors may be used to endorse or promote products derived from 17 | // this software without specific prior written permission. 18 | // 19 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | 31 | syntax = "proto3"; 32 | 33 | package google.protobuf; 34 | 35 | option csharp_namespace = "Google.Protobuf.WellKnownTypes"; 36 | option go_package = "github.com/golang/protobuf/ptypes/empty"; 37 | option java_package = "com.google.protobuf"; 38 | option java_outer_classname = "EmptyProto"; 39 | option java_multiple_files = true; 40 | option objc_class_prefix = "GPB"; 41 | option cc_enable_arenas = true; 42 | 43 | // A generic empty message that you can re-use to avoid defining duplicated 44 | // empty messages in your APIs. A typical example is to use it as the request 45 | // or the response type of an API method. For instance: 46 | // 47 | // service Foo { 48 | // rpc Bar(google.protobuf.Empty) returns (google.protobuf.Empty); 49 | // } 50 | // 51 | // The JSON representation for `Empty` is empty JSON object `{}`. 52 | message Empty {} 53 | -------------------------------------------------------------------------------- /interop/cxx/interop.cc: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | #include "interop_pb.pb.h" 11 | 12 | using namespace std; 13 | 14 | using namespace google::protobuf::util; 15 | 16 | 17 | void usage(const char* argv0) { 18 | cerr << "usage: " << argv0 << " \n"; 19 | } 20 | 21 | vector read_stdin_to_end() { 22 | vector r; 23 | size_t size = 0; 24 | for (;;) { 25 | r.resize(size * 2 + 100); 26 | auto re = read(STDIN_FILENO, r.data() + size, r.size() - size); 27 | if (re == 0) { 28 | r.resize(size); 29 | return r; 30 | } 31 | if (re < 0) { 32 | perror("read"); 33 | _exit(1); 34 | } 35 | size += re; 36 | } 37 | } 38 | 39 | int main(int argc, const char** argv) { 40 | if (argc <= 1) { 41 | usage(argv[0]); 42 | _exit(1); 43 | } 44 | 45 | if (!strcmp(argv[1], "self-test")) { 46 | cerr << "interop OK\n"; 47 | return 0; 48 | } 49 | 50 | if (!strcmp(argv[1], "json-encode")) { 51 | InteropMessageList m; 52 | 53 | auto parse_ok = m.ParseFromFileDescriptor(STDIN_FILENO); 54 | if (!parse_ok) { 55 | cerr << "failed to ParseFromFileDescriptor\n"; 56 | _exit(21); 57 | } 58 | 59 | string json_output; 60 | auto json_ok = MessageToJsonString(m, &json_output); 61 | if (!json_ok.ok()) { 62 | cerr << "failed to MessageToJsonString\n"; 63 | _exit(22); 64 | } 65 | 66 | cout << json_output << "\n"; 67 | return 0; 68 | } 69 | 70 | if (!strcmp(argv[1], "json-decode")) { 71 | InteropMessageList m; 72 | 73 | auto json_text_vec = read_stdin_to_end(); 74 | string json_text(json_text_vec.data(), json_text_vec.size()); 75 | if (json_text.empty()) { 76 | cerr << "empty\n"; 77 | _exit(31); 78 | } 79 | auto json_ok = JsonStringToMessage(json_text, &m); 80 | if (!json_ok.ok()) { 81 | cerr << "failed to JsonStringToMessage: " << json_ok.error_message() << "\n"; 82 | _exit(32); 83 | } 84 | 85 | auto message_ok = m.SerializeToFileDescriptor(STDOUT_FILENO); 86 | if (!message_ok) { 87 | cerr << "failed to SerializeToFileDescriptor\n"; 88 | _exit(33); 89 | } 90 | 91 | return 0; 92 | } 93 | 94 | usage(argv[0]); 95 | return 1; 96 | } 97 | 98 | // vim: set ts=4 sw=4 et: 99 | -------------------------------------------------------------------------------- /protobuf/build.rs: -------------------------------------------------------------------------------- 1 | use std::env; 2 | use std::env::VarError; 3 | use std::io::{Read, Write}; 4 | use std::process; 5 | use std::fs::File; 6 | use std::path::{Path, PathBuf}; 7 | 8 | // % rustc +stable --version 9 | // rustc 1.26.0 (a77568041 2018-05-07) 10 | // % rustc +beta --version 11 | // rustc 1.27.0-beta.1 (03fb2f447 2018-05-09) 12 | // % rustc +nightly --version 13 | // rustc 1.27.0-nightly (acd3871ba 2018-05-10) 14 | fn version_is_nightly(version: &str) -> bool { 15 | version.contains("nightly") 16 | } 17 | 18 | fn cfg_rust_version() { 19 | let rustc = env::var("RUSTC").expect("RUSTC unset"); 20 | 21 | let mut child = process::Command::new(rustc) 22 | .args(&["--version"]) 23 | .stdin(process::Stdio::null()) 24 | .stdout(process::Stdio::piped()) 25 | .spawn() 26 | .expect("spawn rustc"); 27 | 28 | let mut rustc_version = String::new(); 29 | 30 | child 31 | .stdout 32 | .as_mut() 33 | .expect("stdout") 34 | .read_to_string(&mut rustc_version) 35 | .expect("read_to_string"); 36 | assert!(child.wait().expect("wait").success()); 37 | 38 | if version_is_nightly(&rustc_version) { 39 | println!("cargo:rustc-cfg=rustc_nightly"); 40 | } 41 | } 42 | 43 | fn cfg_serde() { 44 | match env::var("CARGO_FEATURE_WITH_SERDE") { 45 | Ok(_) => { 46 | println!("cargo:rustc-cfg=serde"); 47 | } 48 | Err(VarError::NotUnicode(..)) => panic!(), 49 | Err(VarError::NotPresent) => {} 50 | } 51 | } 52 | 53 | fn out_dir() -> PathBuf { 54 | PathBuf::from(env::var("OUT_DIR").expect("OUT_DIR")) 55 | } 56 | 57 | fn version() -> String { 58 | env::var("CARGO_PKG_VERSION").expect("CARGO_PKG_VERSION") 59 | } 60 | 61 | fn write_version() { 62 | let version = version(); 63 | let version_ident = format!("VERSION_{}", version.replace(".", "_").replace("-", "_").to_uppercase()); 64 | let mut file = File::create(Path::join(&out_dir(), "version.rs")).expect("open"); 65 | writeln!(file, "/// protobuf crate version").unwrap(); 66 | writeln!(file, "pub const VERSION: &'static str = \"{}\";", version).unwrap(); 67 | writeln!(file, "/// This symbol is used by codegen").unwrap(); 68 | writeln!(file, "#[doc(hidden)]").unwrap(); 69 | writeln!(file, "pub const VERSION_IDENT: &'static str = \"{}\";", version_ident).unwrap(); 70 | writeln!(file, "/// This symbol can be referenced to assert that proper version of crate is used").unwrap(); 71 | writeln!(file, "pub const {}: () = ();", version_ident).unwrap(); 72 | file.flush().unwrap(); 73 | } 74 | 75 | fn main() { 76 | cfg_rust_version(); 77 | cfg_serde(); 78 | write_version(); 79 | } 80 | -------------------------------------------------------------------------------- /protobuf/src/chars.rs: -------------------------------------------------------------------------------- 1 | #![cfg(feature = "bytes")] 2 | 3 | use std::fmt; 4 | use std::ops::Deref; 5 | use std::str; 6 | 7 | use bytes::Bytes; 8 | 9 | use crate::clear::Clear; 10 | 11 | /// Thin wrapper around `Bytes` which guarantees that bytes are valid UTF-8 string. 12 | /// Should be API-compatible to `String`. 13 | #[derive(Clone, PartialEq, Eq, Hash, PartialOrd, Ord)] 14 | pub struct Chars(Bytes); 15 | 16 | impl Chars { 17 | /// New empty object. 18 | pub fn new() -> Chars { 19 | Chars(Bytes::new()) 20 | } 21 | 22 | /// Try convert from `Bytes` 23 | pub fn from_bytes(bytes: Bytes) -> Result { 24 | str::from_utf8(&bytes)?; 25 | 26 | Ok(Chars(bytes)) 27 | } 28 | 29 | /// Len in bytes. 30 | pub fn len(&self) -> usize { 31 | self.0.len() 32 | } 33 | 34 | /// Self-explanatory 35 | pub fn is_empty(&self) -> bool { 36 | self.0.is_empty() 37 | } 38 | } 39 | 40 | impl<'a> From<&'a str> for Chars { 41 | fn from(src: &'a str) -> Chars { 42 | Chars(Bytes::from(src)) 43 | } 44 | } 45 | 46 | impl From for Chars { 47 | fn from(src: String) -> Chars { 48 | Chars(Bytes::from(src)) 49 | } 50 | } 51 | 52 | impl Into for Chars { 53 | fn into(self) -> String { 54 | unsafe { 55 | // TODO: copies here 56 | String::from_utf8_unchecked(self.0.as_ref().to_owned()) 57 | } 58 | } 59 | } 60 | 61 | impl Default for Chars { 62 | fn default() -> Self { 63 | Chars::new() 64 | } 65 | } 66 | 67 | impl Deref for Chars { 68 | type Target = str; 69 | 70 | fn deref(&self) -> &str { 71 | unsafe { str::from_utf8_unchecked(&self.0) } 72 | } 73 | } 74 | 75 | impl Clear for Chars { 76 | fn clear(&mut self) { 77 | self.0.clear(); 78 | } 79 | } 80 | 81 | impl fmt::Display for Chars { 82 | #[inline] 83 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 84 | fmt::Display::fmt(&**self, f) 85 | } 86 | } 87 | 88 | impl fmt::Debug for Chars { 89 | #[inline] 90 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 91 | fmt::Debug::fmt(&**self, f) 92 | } 93 | } 94 | 95 | #[cfg(test)] 96 | mod test { 97 | use super::Chars; 98 | 99 | #[test] 100 | fn test_display_and_debug() { 101 | let s = "test"; 102 | let string: String = s.into(); 103 | let chars: Chars = s.into(); 104 | 105 | assert_eq!(format!("{}", string), format!("{}", chars)); 106 | assert_eq!(format!("{:?}", string), format!("{:?}", chars)); 107 | } 108 | } 109 | --------------------------------------------------------------------------------