├── test-crates ├── perftest │ ├── misc │ │ ├── src │ │ │ └── lib.rs │ │ ├── Cargo.toml │ │ ├── benches │ │ │ └── write.rs │ │ └── build.rs │ ├── 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 ├── protobuf-fuzz │ ├── src │ │ └── .gitignore │ ├── 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 ├── protobuf-codegen-identical-test │ ├── src │ │ └── lib.rs │ ├── test-data │ │ └── field_after_extension.proto │ └── Cargo.toml ├── interop │ └── cxx │ │ ├── .gitignore │ │ └── compile.sh ├── protobuf-codegen-pure-test │ ├── src │ │ ├── interop │ │ │ └── .gitignore │ │ ├── include_generated │ │ │ └── .gitignore │ │ ├── common │ │ │ ├── mod.rs │ │ │ ├── v2 │ │ │ │ └── .gitignore │ │ │ └── v3 │ │ │ │ └── .gitignore │ │ ├── v2 │ │ │ └── .gitignore │ │ ├── v3 │ │ │ └── .gitignore │ │ ├── google │ │ │ └── protobuf │ │ │ │ └── .gitignore │ │ └── lib.rs │ ├── .gitignore │ ├── README.md │ ├── test.sh │ └── Cargo.toml ├── protobuf-codegen-protoc-test │ ├── src │ │ ├── google │ │ │ ├── mod.rs │ │ │ └── protobuf │ │ │ │ ├── .gitignore │ │ │ │ ├── README.md │ │ │ │ └── import-tests.sh │ │ ├── common │ │ │ ├── v2 │ │ │ │ ├── .gitignore │ │ │ │ ├── test_root.rs │ │ │ │ ├── test_nested_issue_476.rs │ │ │ │ ├── test_dynamic_singular_get_set_pb.proto │ │ │ │ ├── test_dynamic_repeated_get_set_pb.proto │ │ │ │ ├── test_enum_nonunique.rs │ │ │ │ ├── test_import_descriptor.rs │ │ │ │ ├── test_oneof_recursive.rs │ │ │ │ ├── test_map_field_references_nested.rs │ │ │ │ ├── test_enum_nonunique_pb.proto │ │ │ │ ├── test_well_known_types.rs │ │ │ │ ├── test_reflect_no_package_pb.proto │ │ │ │ ├── test_import_descriptor_pb.proto │ │ │ │ ├── test_default.rs │ │ │ │ ├── test_reflect_no_package.rs │ │ │ │ ├── test_sync_pb.proto │ │ │ │ ├── test_map_field_references_nested_pb.proto │ │ │ │ ├── test_default_pb.proto │ │ │ │ ├── test_enum_values_pb.proto │ │ │ │ ├── test_message_getter.rs │ │ │ │ ├── test_message_getter_pb.proto │ │ │ │ ├── test_root_pb.proto │ │ │ │ ├── test_nested_issue_476_pb.proto │ │ │ │ ├── test_any_pb.proto │ │ │ │ ├── test_singular_concat_pb.proto │ │ │ │ ├── test_ident.rs │ │ │ │ ├── test_lite_runtime.rs │ │ │ │ ├── test_enable_lite_runtime.rs │ │ │ │ ├── test_generate_accessors.rs │ │ │ │ ├── test_oneof_nonexhaustive_pb.proto │ │ │ │ ├── test_map_tokio_pb.proto │ │ │ │ ├── test_reflect_issue_564_pb.proto │ │ │ │ ├── test_lite_runtime_pb.proto │ │ │ │ ├── test_enum_alias_pb.proto │ │ │ │ ├── test_enable_lite_runtime_pb.proto │ │ │ │ ├── test_reflect_clear_pb.proto │ │ │ │ ├── test_enum_values.rs │ │ │ │ ├── test_well_known_types_pb.proto │ │ │ │ ├── test_reflect_map_pb.proto │ │ │ │ ├── test_service.rs │ │ │ │ ├── test_oneof_nonexhaustive.rs │ │ │ │ ├── test_oneof_recursive_pb.proto │ │ │ │ ├── test_tokio_bytes_pb.proto │ │ │ │ ├── test_repeated_packed_pb.proto │ │ │ │ ├── test_singular_concat.rs │ │ │ │ ├── test_enum_unknown_values_preserved_pb.proto │ │ │ │ ├── test_tokio_bytes.rs │ │ │ │ ├── test_enum_unknown_values_preserved.rs │ │ │ │ ├── test_generate_accessors_pb.proto │ │ │ │ ├── test_map_simple_pb.proto │ │ │ │ ├── test_service_pb.proto │ │ │ │ ├── test_enum_alias.rs │ │ │ │ ├── test_oneof_basic_pb.proto │ │ │ │ ├── test_sync.rs │ │ │ │ ├── test_map_tokio.rs │ │ │ │ ├── test_any.rs │ │ │ │ ├── test_basic_pb.proto │ │ │ │ ├── test_dynamic_repeated_get_set.rs │ │ │ │ └── test_fmt_json_well_known_pb.proto │ │ │ ├── v3 │ │ │ │ └── .gitignore │ │ │ ├── mod.rs │ │ │ └── README.md │ │ ├── v3 │ │ │ ├── .gitignore │ │ │ ├── README.md │ │ │ ├── test_optional_pb.proto │ │ │ ├── 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 │ │ │ └── bin.rs │ │ ├── v2 │ │ │ ├── README.md │ │ │ ├── .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_is_initialized_pb.proto │ │ │ ├── test_issue_579.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_issue_579_pb.proto │ │ │ ├── test_stream_pb.proto │ │ │ ├── test_tokio_bytes_default_value_pb.proto │ │ │ ├── test_reflect_default_pb.proto │ │ │ ├── test_tokio_bytes_default_value.rs │ │ │ ├── test_required.rs │ │ │ ├── test_is_initialized.rs │ │ │ ├── test_oneof_default_value_pb.proto │ │ │ └── test_reflect_default.rs │ │ ├── include_generated │ │ │ ├── v2.proto │ │ │ ├── v3.proto │ │ │ └── mod.rs │ │ └── lib.rs │ ├── .gitignore │ ├── test.sh │ ├── Cargo.toml │ └── README.md ├── protobuf-test │ ├── src │ │ ├── lib.rs │ │ └── is_initialized_is_always_true_dep.proto │ └── Cargo.toml ├── README.md ├── protobuf-parse-error-test │ ├── test-data │ │ └── extension_in_proto3.proto │ └── Cargo.toml └── protobuf-test-common │ ├── src │ ├── cargo.rs │ ├── lib.rs │ ├── serialize_deserialize_both.rs │ ├── bin │ │ └── varint-encode.rs │ ├── dynamic.rs │ ├── interop.rs │ └── json_tests.rs │ └── Cargo.toml ├── protobuf-examples ├── pure-vs-protoc │ ├── .gitignore │ ├── src │ │ └── protos │ │ │ ├── .gitignore │ │ │ ├── mod.rs │ │ │ └── example.proto │ ├── Cargo.toml │ ├── README.md │ └── build.rs ├── vs-prost │ ├── src │ │ ├── segment.proto │ │ └── triangle.proto │ ├── Cargo.toml │ └── build.rs ├── issue-614 │ ├── foos.proto │ ├── build.rs │ ├── Cargo.toml │ └── examples │ │ └── example-issue-614.rs ├── dynamic │ ├── README.md │ └── Cargo.toml ├── customize-serde │ ├── src │ │ └── customize_example.proto │ ├── Cargo.toml │ ├── README.md │ └── build.rs └── README.md ├── .rustfmt.toml ├── protobuf ├── src │ ├── well_known_types_util │ │ └── mod.rs │ ├── oneof.rs │ ├── byteorder.rs │ ├── reflect │ │ ├── rt │ │ │ ├── mod.rs │ │ │ └── v2.rs │ │ ├── field │ │ │ ├── runtime_field_type.rs │ │ │ ├── protobuf_field_type.rs │ │ │ └── dynamic.rs │ │ ├── acc │ │ │ ├── v2 │ │ │ │ └── mod.rs │ │ │ └── mod.rs │ │ ├── repeated │ │ │ ├── transmute.rs │ │ │ ├── drain_iter.rs │ │ │ └── iter.rs │ │ ├── file │ │ │ └── syntax.rs │ │ ├── oneof │ │ │ └── generated.rs │ │ ├── reflect_eq.rs │ │ ├── type_dynamic.rs │ │ ├── error.rs │ │ ├── dynamic │ │ │ └── optional.rs │ │ ├── service │ │ │ └── index.rs │ │ └── name.rs │ ├── varint │ │ ├── mod.rs │ │ └── generic.rs │ ├── oneof_full.rs │ ├── enum_full.rs │ ├── coded_input_stream │ │ └── input_source.rs │ ├── well_known_types │ │ └── mod.rs │ ├── rt │ │ ├── repeated.rs │ │ ├── message.rs │ │ └── map.rs │ ├── lazy.rs │ ├── fixed.rs │ ├── coded_output_stream │ │ ├── with.rs │ │ └── output_target.rs │ ├── enums.rs │ ├── text_format │ │ └── mod.rs │ ├── special.rs │ └── cached_size.rs ├── Cargo.toml ├── LICENSE.txt └── regenerate.sh ├── protoc-bin ├── src │ ├── lib.rs │ └── bin │ │ └── protoc-bin-print-paths.rs └── Cargo.toml ├── proto ├── doctest_pb.proto └── update.sh ├── protobuf-codegen ├── src │ ├── bin │ │ └── protoc-gen-rs.rs │ ├── gen │ │ ├── field │ │ │ ├── tag.rs │ │ │ └── repeated.rs │ │ ├── rust │ │ │ ├── mod.rs │ │ │ ├── snippets.rs │ │ │ ├── component.rs │ │ │ └── ident_with_path.rs │ │ ├── file_and_mod.rs │ │ ├── inside.rs │ │ ├── map.rs │ │ ├── mod.rs │ │ ├── mod_rs.rs │ │ └── strx.rs │ └── protoc_gen_rs.rs ├── Cargo.toml └── LICENSE.txt ├── protobuf-support ├── src │ ├── lexer │ │ ├── num_lit.rs │ │ ├── json_number_lit.rs │ │ ├── parser_language.rs │ │ ├── mod.rs │ │ ├── int.rs │ │ ├── loc.rs │ │ └── token.rs │ ├── lib.rs │ └── json_name.rs ├── README.md ├── Cargo.toml └── LICENSE.txt ├── google-protobuf-all-protos ├── README.md ├── protobuf │ └── protobuf-git │ │ ├── ruby │ │ ├── tests │ │ │ ├── test_import.proto │ │ │ ├── test_import_proto2.proto │ │ │ ├── test_ruby_package.proto │ │ │ ├── test_ruby_package_proto2.proto │ │ │ └── multi_level_nesting_test.proto │ │ ├── compatibility_tests │ │ │ └── v3.0.0 │ │ │ │ └── tests │ │ │ │ └── test_import.proto │ │ └── src │ │ │ └── main │ │ │ └── sentinel.proto │ │ ├── src │ │ └── google │ │ │ └── protobuf │ │ │ └── compiler │ │ │ └── ruby │ │ │ ├── ruby_generated_code_proto2_import.proto │ │ │ ├── ruby_generated_pkg_implicit.proto │ │ │ ├── ruby_generated_pkg_explicit.proto │ │ │ └── ruby_generated_pkg_explicit_legacy.proto │ │ ├── php │ │ └── tests │ │ │ └── proto │ │ │ ├── test_include.proto │ │ │ ├── test_import_descriptor_proto.proto │ │ │ ├── test_service_namespace.proto │ │ │ ├── empty │ │ │ └── echo.proto │ │ │ ├── test_service.proto │ │ │ ├── test_prefix.proto │ │ │ ├── test_empty_php_namespace.proto │ │ │ ├── test_no_namespace.proto │ │ │ ├── test_descriptors.proto │ │ │ ├── test_php_namespace.proto │ │ │ └── test_wrapper_type_setters.proto │ │ └── csharp │ │ └── protos │ │ ├── unittest_issue6936_b.proto │ │ ├── unittest_issue6936_c.proto │ │ └── unittest_issue6936_a.proto └── update.sh ├── .github └── linters │ ├── .ecrc │ └── .markdown-lint.yml ├── protobuf-parse ├── src │ ├── protoc │ │ └── mod.rs │ ├── pure │ │ ├── mod.rs │ │ └── parse_dependencies.rs │ ├── which_parser.rs │ ├── path.rs │ ├── bin │ │ └── parse-and-typecheck.rs │ ├── test_against_protobuf_protos.rs │ ├── proto │ │ └── mod.rs │ ├── protobuf_path.rs │ ├── rel_path.rs │ ├── case_convert.rs │ └── lib.rs ├── README.md ├── Cargo.toml └── examples │ └── file-descriptor-out-compare.rs ├── protobuf-json-mapping ├── src │ ├── float.rs │ └── lib.rs ├── README.md ├── Cargo.toml └── LICENSE.txt ├── ci-gen ├── Cargo.toml └── src │ └── install_protobuf.rs ├── .editorconfig ├── .gitignore ├── ci └── env-debug.sh ├── BUGREPORTING.md ├── Cargo.toml ├── LICENSE.txt └── CONTRIBUTING.md /test-crates/perftest/misc/src/lib.rs: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /test-crates/protobuf-fuzz/src/.gitignore: -------------------------------------------------------------------------------- 1 | *_pb.rs 2 | -------------------------------------------------------------------------------- /test-crates/perftest/bytes/src/.gitignore: -------------------------------------------------------------------------------- 1 | messages.rs 2 | -------------------------------------------------------------------------------- /test-crates/protobuf-codegen-identical-test/src/lib.rs: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /test-crates/interop/cxx/.gitignore: -------------------------------------------------------------------------------- 1 | interop 2 | interop_pb.pb.* 3 | -------------------------------------------------------------------------------- /test-crates/protobuf-codegen-pure-test/src/interop/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | -------------------------------------------------------------------------------- /protobuf-examples/pure-vs-protoc/.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | **/*.rs.bk 3 | -------------------------------------------------------------------------------- /test-crates/protobuf-codegen-protoc-test/src/google/mod.rs: -------------------------------------------------------------------------------- 1 | mod protobuf; 2 | -------------------------------------------------------------------------------- /test-crates/protobuf-codegen-pure-test/src/include_generated/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | -------------------------------------------------------------------------------- /protobuf-examples/pure-vs-protoc/src/protos/.gitignore: -------------------------------------------------------------------------------- 1 | 2 | example.rs 3 | 4 | -------------------------------------------------------------------------------- /test-crates/protobuf-codegen-protoc-test/.gitignore: -------------------------------------------------------------------------------- 1 | *_pb.rs 2 | *_pb_proto3.rs 3 | -------------------------------------------------------------------------------- /test-crates/protobuf-codegen-pure-test/.gitignore: -------------------------------------------------------------------------------- 1 | *_pb.rs 2 | *_pb_proto3.rs 3 | -------------------------------------------------------------------------------- /test-crates/protobuf-fuzz/fuzz/.gitignore: -------------------------------------------------------------------------------- 1 | 2 | target 3 | corpus 4 | artifacts 5 | -------------------------------------------------------------------------------- /test-crates/protobuf-codegen-protoc-test/src/common/v2/.gitignore: -------------------------------------------------------------------------------- 1 | mod.rs 2 | *_pb.rs 3 | -------------------------------------------------------------------------------- /test-crates/protobuf-codegen-protoc-test/src/common/v3/.gitignore: -------------------------------------------------------------------------------- 1 | *.rs 2 | *.proto 3 | -------------------------------------------------------------------------------- /test-crates/protobuf-codegen-pure-test/src/common/mod.rs: -------------------------------------------------------------------------------- 1 | mod v2; 2 | 3 | mod v3; 4 | -------------------------------------------------------------------------------- /.rustfmt.toml: -------------------------------------------------------------------------------- 1 | group_imports = "StdExternalCrate" 2 | imports_granularity = "Item" 3 | -------------------------------------------------------------------------------- /protobuf/src/well_known_types_util/mod.rs: -------------------------------------------------------------------------------- 1 | mod any; 2 | mod duration; 3 | mod timestamp; 4 | -------------------------------------------------------------------------------- /test-crates/perftest/bytes/src/lib.rs: -------------------------------------------------------------------------------- 1 | #![cfg(feature = "bytes")] 2 | 3 | pub mod messages; 4 | -------------------------------------------------------------------------------- /test-crates/protobuf-codegen-pure-test/README.md: -------------------------------------------------------------------------------- 1 | # Tests for `protobuf-codegen-pure` crate 2 | -------------------------------------------------------------------------------- /test-crates/protobuf-test/src/lib.rs: -------------------------------------------------------------------------------- 1 | #![cfg(test)] 2 | 3 | mod is_initialized_is_always_true; 4 | -------------------------------------------------------------------------------- /protobuf-examples/vs-prost/src/segment.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto2"; 2 | 3 | message Segment { 4 | } 5 | -------------------------------------------------------------------------------- /protoc-bin/src/lib.rs: -------------------------------------------------------------------------------- 1 | //! Just pull the dependency on `protoc-bin-vendored`, nothing to see here. 2 | -------------------------------------------------------------------------------- /test-crates/protobuf-codegen-protoc-test/src/google/protobuf/.gitignore: -------------------------------------------------------------------------------- 1 | unittest*.rs 2 | mod.rs 3 | -------------------------------------------------------------------------------- /test-crates/protobuf-codegen-protoc-test/src/v3/.gitignore: -------------------------------------------------------------------------------- 1 | mod.rs 2 | *_pb.rs 3 | *_pb_proto3.rs 4 | -------------------------------------------------------------------------------- /protobuf/src/oneof.rs: -------------------------------------------------------------------------------- 1 | /// Trait implemented by all oneof types in generated code. 2 | pub trait Oneof {} 3 | -------------------------------------------------------------------------------- /test-crates/protobuf-codegen-protoc-test/src/interop/mod.rs: -------------------------------------------------------------------------------- 1 | // @generated 2 | 3 | pub mod interop_pb; 4 | -------------------------------------------------------------------------------- /test-crates/protobuf-codegen-protoc-test/src/v2/README.md: -------------------------------------------------------------------------------- 1 | Tests for codegen with `syntax = "proto2"`. 2 | -------------------------------------------------------------------------------- /test-crates/protobuf-codegen-protoc-test/src/v3/README.md: -------------------------------------------------------------------------------- 1 | Tests for codegen with `syntax = "proto3"`. 2 | -------------------------------------------------------------------------------- /test-crates/protobuf-codegen-pure-test/src/v2/.gitignore: -------------------------------------------------------------------------------- 1 | # All files in this directory are generated 2 | * 3 | -------------------------------------------------------------------------------- /test-crates/protobuf-codegen-pure-test/src/v3/.gitignore: -------------------------------------------------------------------------------- 1 | # All files in this directory are generated 2 | * 3 | -------------------------------------------------------------------------------- /proto/doctest_pb.proto: -------------------------------------------------------------------------------- 1 | // Messages used in doctests 2 | 3 | syntax = "proto3"; 4 | 5 | message MyMessage { 6 | } 7 | -------------------------------------------------------------------------------- /test-crates/protobuf-codegen-protoc-test/src/v2/.gitignore: -------------------------------------------------------------------------------- 1 | mod.rs 2 | *_pb.rs 3 | struct_.rs 4 | *_pb_proto3.rs 5 | -------------------------------------------------------------------------------- /test-crates/protobuf-codegen-pure-test/src/common/v2/.gitignore: -------------------------------------------------------------------------------- 1 | # All files in this directory are generated 2 | * 3 | -------------------------------------------------------------------------------- /test-crates/protobuf-codegen-pure-test/src/common/v3/.gitignore: -------------------------------------------------------------------------------- 1 | # All files in this directory are generated 2 | * 3 | -------------------------------------------------------------------------------- /test-crates/protobuf-codegen-pure-test/src/google/protobuf/.gitignore: -------------------------------------------------------------------------------- 1 | # All files in this directory are generated 2 | * 3 | -------------------------------------------------------------------------------- /protobuf-codegen/src/bin/protoc-gen-rs.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | protobuf_codegen::protoc_gen_rs::protoc_gen_rust_main(); 3 | } 4 | -------------------------------------------------------------------------------- /protobuf-support/src/lexer/num_lit.rs: -------------------------------------------------------------------------------- 1 | #[derive(Copy, Clone)] 2 | pub enum NumLit { 3 | U64(u64), 4 | F64(f64), 5 | } 6 | -------------------------------------------------------------------------------- /test-crates/protobuf-codegen-protoc-test/src/include_generated/v2.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto2"; 2 | 3 | message V2Message {} 4 | -------------------------------------------------------------------------------- /test-crates/protobuf-codegen-protoc-test/src/v2/test-sanitize-file-name_pb.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto2"; 2 | 3 | message FooBar {} 4 | -------------------------------------------------------------------------------- /google-protobuf-all-protos/README.md: -------------------------------------------------------------------------------- 1 | # .proto 2 | 3 | All `.proto` files from protobuf repository. 4 | 5 | Used in parser tests. 6 | -------------------------------------------------------------------------------- /test-crates/protobuf-codegen-protoc-test/src/v2/test_unknown_suffix_pb.proto3: -------------------------------------------------------------------------------- 1 | syntax = "proto2"; 2 | 3 | message TestUnknownSuffix {} 4 | -------------------------------------------------------------------------------- /.github/linters/.ecrc: -------------------------------------------------------------------------------- 1 | { 2 | "Exclude" : ["expected"], 3 | "Disable": { 4 | "IndentSize": true, 5 | "Indentation": true 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /protobuf-parse/src/protoc/mod.rs: -------------------------------------------------------------------------------- 1 | //! Parse `.proto` files using `protoc` command. 2 | 3 | pub(crate) mod command; 4 | pub(crate) mod parse_and_typecheck; 5 | -------------------------------------------------------------------------------- /test-crates/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 | -------------------------------------------------------------------------------- /test-crates/protobuf-codegen-protoc-test/src/v2/test_import_nonunique_1_pb.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto2"; 2 | 3 | package nonunique_1; 4 | 5 | message Nonunique {} 6 | -------------------------------------------------------------------------------- /test-crates/protobuf-codegen-protoc-test/src/v2/test_import_nonunique_2_pb.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto2"; 2 | 3 | package nonunique_2; 4 | 5 | message Nonunique {} 6 | -------------------------------------------------------------------------------- /test-crates/protobuf-codegen-protoc-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 | -------------------------------------------------------------------------------- /google-protobuf-all-protos/protobuf/protobuf-git/ruby/tests/test_import.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package foo_bar; 4 | 5 | message TestImportedMessage {} 6 | -------------------------------------------------------------------------------- /test-crates/protobuf-codegen-protoc-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 | -------------------------------------------------------------------------------- /protobuf/src/byteorder.rs: -------------------------------------------------------------------------------- 1 | /// Expose cfg as constant to be able to typecheck both versions. 2 | pub(crate) const LITTLE_ENDIAN: bool = cfg!(target_endian = "little"); 3 | -------------------------------------------------------------------------------- /test-crates/protobuf-codegen-protoc-test/src/v2/test_is_initialized_pb.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto2"; 2 | 3 | message TestIsInitialized { 4 | required int32 a = 1; 5 | } 6 | -------------------------------------------------------------------------------- /test-crates/protobuf-codegen-protoc-test/src/v2/test_issue_579.rs: -------------------------------------------------------------------------------- 1 | use super::test_issue_579_pb::Demo; 2 | 3 | #[test] 4 | fn test() { 5 | let _ = Demo::Fizz; 6 | } 7 | -------------------------------------------------------------------------------- /google-protobuf-all-protos/protobuf/protobuf-git/ruby/tests/test_import_proto2.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto2"; 2 | 3 | package foo_bar.proto2; 4 | 5 | message TestImportedMessage {} 6 | -------------------------------------------------------------------------------- /test-crates/README.md: -------------------------------------------------------------------------------- 1 | # Test for rust-protobuf 2 | 3 | Larger tests for rust-protobuf crates. 4 | 5 | (Small tests are implemented as unit tests inside the respective crates.) 6 | -------------------------------------------------------------------------------- /test-crates/protobuf-codegen-protoc-test/src/common/v2/test_nested_issue_476.rs: -------------------------------------------------------------------------------- 1 | use super::test_nested_issue_476_pb::*; 2 | 3 | #[test] 4 | fn test() { 5 | Foo::new(); 6 | } 7 | -------------------------------------------------------------------------------- /test-crates/protobuf-codegen-protoc-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 | -------------------------------------------------------------------------------- /test-crates/protobuf-codegen-pure-test/src/lib.rs: -------------------------------------------------------------------------------- 1 | #![cfg(test)] 2 | 3 | mod v2; 4 | mod v3; 5 | 6 | mod common; 7 | 8 | mod interop; 9 | 10 | mod include_generated; 11 | -------------------------------------------------------------------------------- /test-crates/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 | -------------------------------------------------------------------------------- /test-crates/protobuf-codegen-protoc-test/src/common/v2/test_dynamic_singular_get_set_pb.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto2"; 2 | 3 | message ForDynamicTest { 4 | optional uint32 ff = 1; 5 | } 6 | -------------------------------------------------------------------------------- /google-protobuf-all-protos/protobuf/protobuf-git/ruby/compatibility_tests/v3.0.0/tests/test_import.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package foo_bar; 4 | 5 | message TestImportedMessage {} 6 | -------------------------------------------------------------------------------- /protobuf-json-mapping/src/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 | -------------------------------------------------------------------------------- /ci-gen/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "ci-gen" 3 | version = "0.0.0" 4 | authors = ["Stiopa Koltsov "] 5 | edition = "2021" 6 | publish = false 7 | 8 | [dependencies] 9 | -------------------------------------------------------------------------------- /protobuf-examples/issue-614/foos.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | message Foo { 4 | int32 bar = 1; 5 | oneof baz { 6 | string qux = 2; 7 | bool quux = 3; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /test-crates/protobuf-codegen-protoc-test/src/common/v2/test_dynamic_repeated_get_set_pb.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto2"; 2 | 3 | message ForDynamicRepeatedTest { 4 | repeated uint32 ii = 1; 5 | } 6 | -------------------------------------------------------------------------------- /test-crates/protobuf-codegen-protoc-test/src/common/v2/test_enum_nonunique.rs: -------------------------------------------------------------------------------- 1 | use super::test_enum_nonunique_pb::*; 2 | 3 | #[test] 4 | fn test() { 5 | let _ = message_a::EnumA::FOO; 6 | } 7 | -------------------------------------------------------------------------------- /test-crates/protobuf-codegen-protoc-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 | -------------------------------------------------------------------------------- /test-crates/protobuf-codegen-protoc-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 | -------------------------------------------------------------------------------- /test-crates/protobuf-codegen-protoc-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 | -------------------------------------------------------------------------------- /test-crates/protobuf-test/src/is_initialized_is_always_true_dep.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto2"; 2 | 3 | message DepAlwaysTrue {} 4 | 5 | message DepNotAlwaysTrue { 6 | required int32 a = 1; 7 | } 8 | -------------------------------------------------------------------------------- /test-crates/protobuf-codegen-protoc-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-codegen/src/gen/field/tag.rs: -------------------------------------------------------------------------------- 1 | use protobuf::rt::WireType; 2 | 3 | pub(crate) fn make_tag(field_number: u32, wire_type: WireType) -> u32 { 4 | (field_number << 3) | (wire_type as u32) 5 | } 6 | -------------------------------------------------------------------------------- /test-crates/protobuf-codegen-protoc-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 | -------------------------------------------------------------------------------- /test-crates/protobuf-codegen-protoc-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 | -------------------------------------------------------------------------------- /google-protobuf-all-protos/protobuf/protobuf-git/src/google/protobuf/compiler/ruby/ruby_generated_code_proto2_import.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto2"; 2 | 3 | package A.B.C; 4 | 5 | message TestImportedMessage {} 6 | -------------------------------------------------------------------------------- /google-protobuf-all-protos/protobuf/protobuf-git/ruby/tests/test_ruby_package.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package foo_bar; 4 | 5 | option ruby_package = "A::B"; 6 | 7 | message TestRubyPackageMessage {} 8 | -------------------------------------------------------------------------------- /test-crates/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 | -------------------------------------------------------------------------------- /test-crates/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 | -------------------------------------------------------------------------------- /test-crates/protobuf-codegen-protoc-test/src/common/v2/test_map_field_references_nested.rs: -------------------------------------------------------------------------------- 1 | use super::test_map_field_references_nested_pb::*; 2 | 3 | #[test] 4 | fn test() { 5 | MapFieldReferencesNested::new(); 6 | } 7 | -------------------------------------------------------------------------------- /test-crates/protobuf-codegen-protoc-test/src/include_generated/v3.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | import "v2.proto"; 4 | 5 | message V3Message { 6 | // Test we can include other protos 7 | V2Message v2 = 1; 8 | } 9 | -------------------------------------------------------------------------------- /test-crates/protobuf-codegen-protoc-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 | -------------------------------------------------------------------------------- /google-protobuf-all-protos/protobuf/protobuf-git/src/google/protobuf/compiler/ruby/ruby_generated_pkg_implicit.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package one.two.a_three; 4 | 5 | message Four { 6 | string a_string = 1; 7 | } 8 | -------------------------------------------------------------------------------- /test-crates/protobuf-codegen-protoc-test/src/common/v2/test_enum_nonunique_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 | -------------------------------------------------------------------------------- /test-crates/protobuf-codegen-protoc-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 | -------------------------------------------------------------------------------- /google-protobuf-all-protos/protobuf/protobuf-git/ruby/tests/test_ruby_package_proto2.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto2"; 2 | 3 | package foo_bar_proto2; 4 | 5 | option ruby_package = "A::B::Proto2"; 6 | 7 | message TestRubyPackageMessage {} 8 | -------------------------------------------------------------------------------- /test-crates/protobuf-codegen-protoc-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 | -------------------------------------------------------------------------------- /test-crates/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 | -------------------------------------------------------------------------------- /test-crates/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 | -------------------------------------------------------------------------------- /test-crates/protobuf-codegen-protoc-test/src/common/v2/test_reflect_no_package_pb.proto: -------------------------------------------------------------------------------- 1 | // This file intentionally has no `package` declaration. 2 | 3 | syntax = "proto2"; 4 | 5 | message Ignored { 6 | optional int32 i = 1; 7 | } 8 | -------------------------------------------------------------------------------- /test-crates/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 | -------------------------------------------------------------------------------- /test-crates/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 | -------------------------------------------------------------------------------- /test-crates/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 | -------------------------------------------------------------------------------- /test-crates/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 | -------------------------------------------------------------------------------- /test-crates/protobuf-codegen-protoc-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 | -------------------------------------------------------------------------------- /.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 | 8 | [protoc-bin-vendored/bin/*] 9 | end_of_line = 10 | charset = 11 | indent_style = 12 | indent_size = 13 | -------------------------------------------------------------------------------- /protobuf-examples/issue-614/build.rs: -------------------------------------------------------------------------------- 1 | use protobuf_codegen::Codegen; 2 | 3 | fn main() { 4 | Codegen::new() 5 | .input("foos.proto") 6 | .include(".") 7 | .cargo_out_dir("p") 8 | .run_from_script(); 9 | } 10 | -------------------------------------------------------------------------------- /protobuf-json-mapping/README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | JSON printer and parser which tries to follow 4 | [protobuf conventions](https://developers.google.com/protocol-buffers/docs/proto3#json). 5 | 6 | 7 | -------------------------------------------------------------------------------- /test-crates/protobuf-codegen-protoc-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 | -------------------------------------------------------------------------------- /test-crates/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 | -------------------------------------------------------------------------------- /test-crates/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 | -------------------------------------------------------------------------------- /test-crates/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-codegen/src/gen/rust/mod.rs: -------------------------------------------------------------------------------- 1 | pub(crate) mod component; 2 | pub(crate) mod ident; 3 | pub(crate) mod ident_with_path; 4 | pub(crate) mod keywords; 5 | pub(crate) mod path; 6 | pub(crate) mod quote; 7 | pub(crate) mod rel_path; 8 | pub(crate) mod snippets; 9 | -------------------------------------------------------------------------------- /test-crates/protobuf-codegen-protoc-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().i()); 7 | } 8 | -------------------------------------------------------------------------------- /test-crates/protobuf-codegen-protoc-test/src/common/v2/test_reflect_no_package.rs: -------------------------------------------------------------------------------- 1 | #[test] 2 | fn test_no_package() { 3 | let file_descriptor = super::test_reflect_no_package_pb::file_descriptor(); 4 | assert!(!file_descriptor.proto().has_package()); 5 | } 6 | -------------------------------------------------------------------------------- /test-crates/protobuf-codegen-protoc-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 | -------------------------------------------------------------------------------- /test-crates/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/src/reflect/rt/mod.rs: -------------------------------------------------------------------------------- 1 | //! This module contains functions references for reflection in generated code. 2 | 3 | #![doc(hidden)] 4 | 5 | pub mod v2; 6 | 7 | pub use crate::reflect::acc::FieldAccessor; 8 | pub use crate::reflect::runtime_types::RuntimeTypeMessage; 9 | -------------------------------------------------------------------------------- /test-crates/protobuf-codegen-protoc-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 | -------------------------------------------------------------------------------- /.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-rs 15 | target/ 16 | Cargo.lock 17 | .idea 18 | *.iml 19 | -------------------------------------------------------------------------------- /google-protobuf-all-protos/protobuf/protobuf-git/src/google/protobuf/compiler/ruby/ruby_generated_pkg_explicit.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package one.two.a_three; 4 | 5 | option ruby_package = "A::B::C"; 6 | 7 | message Four { 8 | string a_string = 1; 9 | } 10 | -------------------------------------------------------------------------------- /protobuf-codegen/src/gen/file_and_mod.rs: -------------------------------------------------------------------------------- 1 | use crate::customize::Customize; 2 | use crate::gen::rust::rel_path::RustRelativePath; 3 | 4 | pub(crate) struct FileAndMod { 5 | pub file: String, 6 | pub relative_mod: RustRelativePath, 7 | pub customize: Customize, 8 | } 9 | -------------------------------------------------------------------------------- /protobuf/src/varint/mod.rs: -------------------------------------------------------------------------------- 1 | pub(crate) mod decode; 2 | pub(crate) mod encode; 3 | pub(crate) mod generic; 4 | 5 | /// Encoded varint message is not longer than 10 bytes. 6 | pub(crate) const MAX_VARINT_ENCODED_LEN: usize = 10; 7 | pub(crate) const MAX_VARINT32_ENCODED_LEN: usize = 5; 8 | -------------------------------------------------------------------------------- /test-crates/protobuf-codegen-protoc-test/src/common/v2/test_map_field_references_nested_pb.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto2"; 2 | 3 | message MapFieldReferencesNested { 4 | message NestedMessageReferencedInMapEntry {} 5 | 6 | map x = 1; 7 | } 8 | -------------------------------------------------------------------------------- /test-crates/protobuf-codegen-protoc-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-examples/dynamic/README.md: -------------------------------------------------------------------------------- 1 | # Dynamic messages 2 | 3 | Example how to create "dynamic" messages: 4 | these are created using only protobuf schema without generated files. 5 | 6 | 99% of users won't need this. 7 | 8 | Note this crate does not depend on `protobuf-codegen` crate. 9 | -------------------------------------------------------------------------------- /protobuf-support/README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Supporting code for protobuf crates 4 | 5 | Code in this crate is used in protobuf crates like `protobuf` or `protobuf-parse`. 6 | None of code in this crate has public API. 7 | 8 | 9 | -------------------------------------------------------------------------------- /test-crates/protobuf-parse-error-test/test-data/extension_in_proto3.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | // expected protoc: Extension ranges are not allowed in proto3 4 | // expected pure: Not allowed in this context: extensions 5 | 6 | message FooBar { 7 | extensions 1000 to max; 8 | } 9 | -------------------------------------------------------------------------------- /protobuf/src/oneof_full.rs: -------------------------------------------------------------------------------- 1 | use crate::reflect::OneofDescriptor; 2 | use crate::Oneof; 3 | 4 | /// Implemented by all oneof types when lite runtime is not enabled. 5 | pub trait OneofFull: Oneof { 6 | /// Descriptor object for this oneof. 7 | fn descriptor() -> OneofDescriptor; 8 | } 9 | -------------------------------------------------------------------------------- /test-crates/protobuf-codegen-protoc-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 | -------------------------------------------------------------------------------- /test-crates/protobuf-codegen-protoc-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 | -------------------------------------------------------------------------------- /test-crates/protobuf-codegen-protoc-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 | -------------------------------------------------------------------------------- /test-crates/protobuf-codegen-protoc-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 | -------------------------------------------------------------------------------- /google-protobuf-all-protos/protobuf/protobuf-git/src/google/protobuf/compiler/ruby/ruby_generated_pkg_explicit_legacy.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package one.two.a_three.and; 4 | 5 | option ruby_package = "AA.BB.CC"; 6 | 7 | message Four { 8 | string another_string = 1; 9 | } 10 | -------------------------------------------------------------------------------- /test-crates/protobuf-codegen-protoc-test/src/common/v2/test_message_getter.rs: -------------------------------------------------------------------------------- 1 | use super::test_message_getter_pb::MessageForTestGetter; 2 | 3 | #[test] 4 | fn get_returns_default_value() { 5 | let m = MessageForTestGetter::new(); 6 | assert_eq!(0, m.i()); 7 | assert_eq!(false, m.b()); 8 | } 9 | -------------------------------------------------------------------------------- /test-crates/protobuf-codegen-protoc-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 | -------------------------------------------------------------------------------- /test-crates/protobuf-codegen-protoc-test/src/common/v2/test_message_getter_pb.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto2"; 2 | 3 | import "rustproto.proto"; 4 | option (rustproto.generate_accessors_all) = true; 5 | 6 | message MessageForTestGetter { 7 | optional uint32 i = 1; 8 | optional bool b = 2; 9 | } 10 | -------------------------------------------------------------------------------- /test-crates/protobuf-codegen-protoc-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 | -------------------------------------------------------------------------------- /test-crates/protobuf-codegen-protoc-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-examples/customize-serde/src/customize_example.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto2"; 2 | 3 | message Fruit { 4 | optional string name = 1; 5 | optional float weight = 2; 6 | optional Shape shape = 3; 7 | } 8 | 9 | enum Shape { 10 | UNKNOWN = 0; 11 | CIRCLE = 1; 12 | SQUARE = 2; 13 | } 14 | -------------------------------------------------------------------------------- /test-crates/protobuf-codegen-protoc-test/src/common/v2/test_nested_issue_476_pb.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto2"; 2 | 3 | message Foo { 4 | message Bar { 5 | message Baz { } 6 | oneof bar_content { 7 | Baz baz = 1; 8 | uint32 integer = 2; 9 | } 10 | } 11 | optional Bar bar = 1; 12 | } 13 | -------------------------------------------------------------------------------- /protobuf-support/src/lib.rs: -------------------------------------------------------------------------------- 1 | //! # Supporting code for protobuf crates 2 | //! 3 | //! Code in this crate is used in protobuf crates like `protobuf` or `protobuf-parse`. 4 | //! None of code in this crate has public API. 5 | 6 | pub mod json_name; 7 | pub mod lexer; 8 | pub mod text_format; 9 | pub mod toposort; 10 | -------------------------------------------------------------------------------- /test-crates/protobuf-codegen-protoc-test/src/common/README.md: -------------------------------------------------------------------------------- 1 | # Common tests for v2 and v3 codegen 2 | 3 | When behavior should be identical. 4 | 5 | The source is `v2` folder. 6 | 7 | For `v3` files are copied from `v2` folder with: 8 | * `syntax` instruction patched 9 | * `optional` field prefix is removed. 10 | -------------------------------------------------------------------------------- /.github/linters/.markdown-lint.yml: -------------------------------------------------------------------------------- 1 | { 2 | # Line length 3 | "MD013": false, 4 | # Headings should be surrounded by blank lines 5 | "MD022": false, 6 | # Multiple headings with the same content 7 | "MD024": false, 8 | # Lists should be surrounded by blank lines 9 | "MD032": false 10 | } 11 | -------------------------------------------------------------------------------- /protobuf-support/src/lexer/json_number_lit.rs: -------------------------------------------------------------------------------- 1 | use std::fmt; 2 | 3 | #[derive(Clone, Debug, Eq, PartialEq)] 4 | pub struct JsonNumberLit(pub 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 | -------------------------------------------------------------------------------- /test-crates/protobuf-codegen-protoc-test/src/common/v2/test_any_pb.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto2"; 2 | 3 | import "rustproto.proto"; 4 | option (rustproto.generate_accessors_all) = true; 5 | 6 | package test_any; 7 | 8 | message MessageOne { 9 | optional int32 i = 1; 10 | } 11 | 12 | message MessageTwo { 13 | 14 | } 15 | -------------------------------------------------------------------------------- /test-crates/protobuf-codegen-protoc-test/src/v3/test_optional_pb.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | message TestOptionalProto3 { 4 | int32 non_optional = 1; 5 | oneof one { 6 | string one_field_1 = 11; 7 | int32 one_field_2 = 12; 8 | } 9 | optional int32 iii = 31; 10 | optional string sss = 22; 11 | } 12 | -------------------------------------------------------------------------------- /protobuf-parse/src/pure/mod.rs: -------------------------------------------------------------------------------- 1 | //! Pure rust `.proto` file parser. 2 | 3 | pub(crate) mod convert; 4 | pub(crate) mod model; 5 | pub(crate) mod parse_and_typecheck; 6 | pub(crate) mod parse_dependencies; 7 | mod parser; 8 | 9 | pub use parse_and_typecheck::parse_and_typecheck_custom; 10 | pub use parse_dependencies::*; 11 | -------------------------------------------------------------------------------- /protobuf-support/src/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 | -------------------------------------------------------------------------------- /test-crates/protobuf-codegen-protoc-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 | -------------------------------------------------------------------------------- /test-crates/protobuf-codegen-protoc-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.double_field()); 7 | assert_eq!("ss", m.string_field()); 8 | assert_eq!(b"bb", m.bytes_field()); 9 | } 10 | -------------------------------------------------------------------------------- /protobuf-support/src/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 | pub mod json_number_lit; 6 | pub mod lexer_impl; 7 | pub mod loc; 8 | pub mod num_lit; 9 | pub mod parser_language; 10 | pub mod str_lit; 11 | pub mod token; 12 | pub mod tokenizer; 13 | -------------------------------------------------------------------------------- /test-crates/protobuf-codegen-protoc-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 | -------------------------------------------------------------------------------- /test-crates/protobuf-codegen-protoc-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 | mod v2; 11 | mod v3; 12 | 13 | mod common; 14 | 15 | mod google; 16 | 17 | mod interop; 18 | 19 | mod include_generated; 20 | -------------------------------------------------------------------------------- /test-crates/protobuf-codegen-protoc-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 | -------------------------------------------------------------------------------- /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-examples/dynamic/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "protobuf-examples-dynamic" 3 | version = "0.0.0" 4 | authors = ["Stepan Koltsov "] 5 | edition = "2021" 6 | publish = false 7 | 8 | [dependencies] 9 | protobuf = { path = "../../protobuf" } 10 | protobuf-parse = { path = "../../protobuf-parse" } 11 | tempfile = "3" 12 | -------------------------------------------------------------------------------- /test-crates/protobuf-codegen-protoc-test/src/include_generated/mod.rs: -------------------------------------------------------------------------------- 1 | // Include single mod.rs which references two mods: `v2` and `v3` 2 | include!(concat!(env!("OUT_DIR"), "/include_generated/mod.rs")); 3 | 4 | use v2::V2Message; 5 | use v3::V3Message; 6 | 7 | #[test] 8 | fn test() { 9 | let _ = V2Message::new(); 10 | let _ = V3Message::new(); 11 | } 12 | -------------------------------------------------------------------------------- /test-crates/protobuf-codegen-protoc-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 | -------------------------------------------------------------------------------- /test-crates/perftest/vs-cxx/build.rs: -------------------------------------------------------------------------------- 1 | use protobuf_codegen::Codegen; 2 | use protobuf_codegen::Customize; 3 | 4 | fn main() { 5 | Codegen::new() 6 | .pure() 7 | .out_dir(".") 8 | .include(".") 9 | .input("perftest_data.proto") 10 | .customize(Customize::default().gen_mod_rs(false)) 11 | .run_from_script(); 12 | } 13 | -------------------------------------------------------------------------------- /test-crates/protobuf-codegen-protoc-test/src/common/v2/test_ident.rs: -------------------------------------------------------------------------------- 1 | use protobuf::MessageFull; 2 | 3 | use super::test_ident_pb::*; 4 | 5 | #[test] 6 | fn test() { 7 | let _ = TestType::new(); 8 | } 9 | 10 | #[test] 11 | fn test_reflect() { 12 | Self_::new(); 13 | // instantiate reflection 14 | assert_eq!("Self", Self_::descriptor().name()); 15 | } 16 | -------------------------------------------------------------------------------- /test-crates/protobuf-codegen-protoc-test/src/v2/test_issue_579_pb.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto2"; 2 | 3 | package bug.repro; 4 | 5 | import "google/protobuf/descriptor.proto"; 6 | 7 | extend google.protobuf.EnumValueOptions { 8 | optional google.protobuf.FieldDescriptorProto.Type foo = 50000; 9 | } 10 | 11 | enum Demo { 12 | Fizz = 1 [(foo) = TYPE_UINT64]; 13 | } 14 | -------------------------------------------------------------------------------- /protobuf-support/src/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 | -------------------------------------------------------------------------------- /test-crates/protobuf-codegen-protoc-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 | let _ = format!("{:?}", m); 13 | } 14 | -------------------------------------------------------------------------------- /test-crates/protobuf-codegen-identical-test/test-data/field_after_extension.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto2"; 2 | 3 | message Foo { 4 | extensions 100 to 200; 5 | } 6 | 7 | message Bar { 8 | optional int32 xx1 = 1; 9 | optional int32 xx2 = 201; 10 | extend Foo { 11 | optional int32 yyy = 111; 12 | } 13 | optional int32 zz1 = 2; 14 | optional int32 zz2 = 202; 15 | } 16 | -------------------------------------------------------------------------------- /test-crates/protobuf-codegen-protoc-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 | -------------------------------------------------------------------------------- /google-protobuf-all-protos/protobuf/protobuf-git/php/tests/proto/test_include.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package bar; 4 | 5 | message TestInclude { 6 | int32 a = 1; 7 | } 8 | 9 | message TestLegacyMessage { 10 | NestedMessage message = 1; 11 | NestedEnum enum = 2; 12 | message NestedMessage { 13 | int32 a = 1; 14 | } 15 | enum NestedEnum { 16 | ZERO = 0; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /protobuf/src/reflect/field/runtime_field_type.rs: -------------------------------------------------------------------------------- 1 | use crate::reflect::RuntimeType; 2 | 3 | /// Reflective representation of field type. 4 | pub enum RuntimeFieldType { 5 | /// Singular field (required, optional for proto2 or singular for proto3) 6 | Singular(RuntimeType), 7 | /// Repeated field 8 | Repeated(RuntimeType), 9 | /// Map field 10 | Map(RuntimeType, RuntimeType), 11 | } 12 | -------------------------------------------------------------------------------- /test-crates/protobuf-codegen-protoc-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().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 | -------------------------------------------------------------------------------- /test-crates/protobuf-codegen-protoc-test/src/common/v2/test_oneof_nonexhaustive_pb.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto2"; 2 | 3 | import "rustproto.proto"; 4 | 5 | package test_oneof; 6 | 7 | message MessageWithOneofNonexhaustiveDisabled{ 8 | option (rustproto.oneofs_non_exhaustive) = false; 9 | 10 | oneof one { 11 | uint32 first_field = 1; 12 | string second_field = 2; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /test-crates/protobuf-codegen-protoc-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 | -------------------------------------------------------------------------------- /google-protobuf-all-protos/protobuf/protobuf-git/php/tests/proto/test_import_descriptor_proto.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package foo; 4 | 5 | import "google/protobuf/descriptor.proto"; 6 | 7 | message TestImportDescriptorProto { 8 | extend google.protobuf.MethodOptions { 9 | int32 a = 72295727; 10 | } 11 | } 12 | 13 | extend google.protobuf.MethodOptions { 14 | int32 a = 72295728; 15 | } 16 | 17 | -------------------------------------------------------------------------------- /protobuf-examples/vs-prost/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "protobuf-examples-vs-prost" 3 | version = "0.0.0" 4 | authors = ["Stepan Koltsov "] 5 | edition = "2021" 6 | publish = false 7 | 8 | [dependencies] 9 | protobuf = { path = "../../protobuf" } 10 | prost = "0.10.1" 11 | 12 | [build-dependencies] 13 | protobuf-codegen = { path = "../../protobuf-codegen" } 14 | prost-build = "0.9.0" 15 | -------------------------------------------------------------------------------- /protobuf-examples/vs-prost/build.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | protobuf_codegen::Codegen::new() 3 | .include("src") 4 | .inputs(["src/segment.proto", "src/triangle.proto"]) 5 | .cargo_out_dir("rust_protobuf_protos") 6 | .run_from_script(); 7 | 8 | prost_build::Config::new() 9 | .compile_protos(&["src/segment.proto", "src/triangle.proto"], &["src"]) 10 | .unwrap(); 11 | } 12 | -------------------------------------------------------------------------------- /google-protobuf-all-protos/protobuf/protobuf-git/php/tests/proto/test_service_namespace.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | import "proto/test_service.proto"; 4 | 5 | package foo; 6 | 7 | option php_generic_services = true; 8 | option php_namespace = "Bar"; 9 | 10 | service OtherGreeter { 11 | rpc SayHello (HelloRequest) returns (HelloReply) {} 12 | rpc SayHelloAgain (HelloRequest) returns (HelloReply) {} 13 | } 14 | -------------------------------------------------------------------------------- /google-protobuf-all-protos/update.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -ex 4 | 5 | cd "$(dirname "$0")" 6 | 7 | rm -rf protobuf protobuf-git 8 | 9 | mkdir protobuf 10 | 11 | git clone --branch v3.19.4 --depth 1 https://github.com/google/protobuf/ protobuf-git 12 | 13 | rsync -r --include='*.proto' --include='*/' --exclude='*' --prune-empty-dirs protobuf-git protobuf 14 | 15 | rm -rf protobuf-git 16 | 17 | # vim: set ts=4 sw=4 et: 18 | -------------------------------------------------------------------------------- /test-crates/protobuf-codegen-protoc-test/src/common/v2/test_map_tokio_pb.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto2"; 2 | 3 | import "rustproto.proto"; 4 | 5 | option (rustproto.tokio_bytes_all) = true; 6 | option (rustproto.tokio_bytes_for_string_all) = true; 7 | 8 | message TestMapTokio { 9 | map string_to_int32 = 1; 10 | map int32_to_string = 2; 11 | map int32_to_bytes = 3; 12 | } 13 | -------------------------------------------------------------------------------- /test-crates/protobuf-codegen-protoc-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 | -------------------------------------------------------------------------------- /test-crates/protobuf-codegen-protoc-test/src/common/v2/test_reflect_issue_564_pb.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto2"; 2 | 3 | import "rustproto.proto"; 4 | option (rustproto.generate_accessors_all) = true; 5 | 6 | message Issue564 { 7 | enum TestEnum { 8 | TEST_ENUM_VALUE_A = 0; 9 | TEST_ENUM_VALUE_B = 1; 10 | } 11 | 12 | message TestMessage {} 13 | 14 | optional TestEnum ee = 1; 15 | optional TestMessage mm = 2; 16 | } 17 | -------------------------------------------------------------------------------- /test-crates/protobuf-fuzz/build.rs: -------------------------------------------------------------------------------- 1 | use protobuf_codegen::Codegen; 2 | use protobuf_codegen::Customize; 3 | 4 | fn main() { 5 | protobuf_test_common::build::clean_old_files(); 6 | 7 | Codegen::new() 8 | .pure() 9 | .out_dir("src") 10 | .include("src") 11 | .input("src/all_types_pb.proto") 12 | .customize(Customize::default().gen_mod_rs(false)) 13 | .run_from_script(); 14 | } 15 | -------------------------------------------------------------------------------- /protoc-bin/src/bin/protoc-bin-print-paths.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | println!( 3 | "PROTOC={}", 4 | protoc_bin_vendored::protoc_bin_path() 5 | .unwrap() 6 | .to_str() 7 | .unwrap() 8 | ); 9 | println!( 10 | "PROTOBUF_INCLUDE={}", 11 | protoc_bin_vendored::include_path() 12 | .unwrap() 13 | .to_str() 14 | .unwrap() 15 | ); 16 | } 17 | -------------------------------------------------------------------------------- /google-protobuf-all-protos/protobuf/protobuf-git/php/tests/proto/empty/echo.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package empty.echo; 4 | 5 | message TestEmptyPackage { 6 | int32 a = 1; 7 | 8 | // Test nested messages, enums, and reserved names 9 | NestedMessage nested_message = 2; 10 | NestedEnum nested_enum = 3; 11 | message NestedMessage { 12 | int32 a = 1; 13 | } 14 | enum NestedEnum { 15 | ZERO = 0; 16 | }; 17 | } 18 | -------------------------------------------------------------------------------- /protobuf-parse/src/which_parser.rs: -------------------------------------------------------------------------------- 1 | /// Which parse to use to parse `.proto` files. 2 | #[derive(Debug, Copy, Clone)] 3 | pub(crate) enum WhichParser { 4 | /// Pure Rust parser implemented by this crate. 5 | Pure, 6 | /// Parse `.proto` files using `protoc --descriptor_set_out=...` command. 7 | Protoc, 8 | } 9 | 10 | impl Default for WhichParser { 11 | fn default() -> Self { 12 | WhichParser::Pure 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /protobuf-codegen/src/gen/rust/snippets.rs: -------------------------------------------------------------------------------- 1 | pub(crate) const EXPR_NONE: &str = "::std::option::Option::None"; 2 | pub(crate) const EXPR_VEC_NEW: &str = "::std::vec::Vec::new()"; 3 | 4 | fn expr_vec_with_capacity(capacity: &str) -> String { 5 | format!("::std::vec::Vec::with_capacity({})", capacity) 6 | } 7 | 8 | pub(crate) fn expr_vec_with_capacity_const(capacity: usize) -> String { 9 | expr_vec_with_capacity(&capacity.to_string()) 10 | } 11 | -------------------------------------------------------------------------------- /protobuf-examples/vs-prost/src/triangle.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | enum Color { 4 | UNKNOWN = 0; 5 | RED = 1; 6 | GREEN = 2; 7 | BLUE = 3; 8 | } 9 | 10 | message Properties { 11 | oneof properties { 12 | int32 p1 = 1; 13 | string p2 = 2; 14 | } 15 | } 16 | 17 | message Triangle { 18 | string description = 1; 19 | Color color = 2; 20 | Properties properties = 3; 21 | int32 struct = 4; 22 | } 23 | -------------------------------------------------------------------------------- /test-crates/protobuf-codegen-protoc-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 | -------------------------------------------------------------------------------- /google-protobuf-all-protos/protobuf/protobuf-git/php/tests/proto/test_service.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package foo; 4 | 5 | option php_generic_services = true; 6 | 7 | service Greeter { 8 | rpc SayHello (HelloRequest) returns (HelloReply) {} 9 | rpc SayHelloAgain (HelloRequest) returns (HelloReply) {} 10 | } 11 | 12 | message HelloRequest { 13 | string name = 1; 14 | } 15 | 16 | message HelloReply { 17 | string message = 1; 18 | } 19 | -------------------------------------------------------------------------------- /protobuf-codegen/src/gen/inside.rs: -------------------------------------------------------------------------------- 1 | use crate::customize::Customize; 2 | use crate::gen::rust::path::RustPath; 3 | 4 | /// Path to `protobuf` crate, different when `.proto` file is 5 | /// used inside or outside of protobuf crate. 6 | pub(crate) fn protobuf_crate_path(customize: &Customize) -> RustPath { 7 | match customize.inside_protobuf { 8 | Some(true) => RustPath::from("crate"), 9 | _ => RustPath::from("::protobuf"), 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /test-crates/protobuf-codegen-protoc-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 | -------------------------------------------------------------------------------- /google-protobuf-all-protos/protobuf/protobuf-git/csharp/protos/unittest_issue6936_b.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | import "unittest_issue6936_a.proto"; 4 | 5 | package unittest_issues; 6 | 7 | option csharp_namespace = "UnitTest.Issues.TestProtos"; 8 | 9 | // This file is used as part of a unit test for issue 6936 10 | // We don't need to use it, we just have to import it in "unittest_issue6936_c.proto" 11 | 12 | message Foo { 13 | option (opt) = "foo"; 14 | } -------------------------------------------------------------------------------- /test-crates/protobuf-codegen-protoc-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 | -------------------------------------------------------------------------------- /test-crates/protobuf-codegen-protoc-test/src/common/v2/test_reflect_clear_pb.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto2"; 2 | 3 | import "rustproto.proto"; 4 | option (rustproto.generate_accessors_all) = true; 5 | 6 | package test_reflect_clear; 7 | 8 | message TestMessage { 9 | message Nested { 10 | } 11 | 12 | optional int32 a = 1; 13 | optional string b = 2; 14 | optional Nested c = 3; 15 | repeated int32 d = 4; 16 | map e = 5; 17 | } 18 | -------------------------------------------------------------------------------- /protobuf-examples/issue-614/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "protobuf-examples-issue-614" 3 | version = "0.0.0" 4 | authors = ["Stepan Koltsov "] 5 | edition = "2021" 6 | publish = false 7 | description= """ 8 | Example for https://github.com/stepancheg/rust-protobuf/issues/614 9 | """ 10 | 11 | [dependencies] 12 | protobuf = { path = "../../protobuf" } 13 | 14 | [build-dependencies] 15 | protobuf-codegen = { path = "../../protobuf-codegen" } 16 | -------------------------------------------------------------------------------- /protobuf-examples/pure-vs-protoc/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "protobuf-examples-pure-vs-protoc" 3 | version = "0.0.0" 4 | authors = ["Jeff Garzik "] 5 | edition = "2021" 6 | publish = false 7 | 8 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 9 | 10 | [dependencies] 11 | protobuf = { path = "../../protobuf" } 12 | 13 | [build-dependencies] 14 | protobuf-codegen = { path = "../../protobuf-codegen" } 15 | -------------------------------------------------------------------------------- /google-protobuf-all-protos/protobuf/protobuf-git/php/tests/proto/test_prefix.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | option php_class_prefix = "Prefix"; 4 | 5 | message TestPrefix { 6 | int32 a = 1; 7 | NestedMessage nested_message = 2; 8 | NestedEnum nested_enum = 3; 9 | message NestedMessage { 10 | int32 a = 1; 11 | } 12 | enum NestedEnum { 13 | ZERO = 0; 14 | }; 15 | } 16 | 17 | // Test prefix for reserved words. 18 | message Empty { 19 | int32 a = 1; 20 | } 21 | -------------------------------------------------------------------------------- /test-crates/protobuf-codegen-protoc-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 | -------------------------------------------------------------------------------- /test-crates/protobuf-codegen-protoc-test/src/v2/test_stream_pb.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto2"; 2 | 3 | 4 | message Req { 5 | required int32 a = 1; 6 | repeated string b = 2; 7 | } 8 | 9 | message Resp { 10 | required int32 status = 1; 11 | } 12 | 13 | service TestService { 14 | rpc test_client_streaming(stream Req) returns (Resp); 15 | rpc test_server_streaming(Req) returns (stream Resp); 16 | rpc test_bi_streaming(stream Req) returns (stream Resp); 17 | } 18 | 19 | -------------------------------------------------------------------------------- /protobuf-examples/pure-vs-protoc/src/protos/mod.rs: -------------------------------------------------------------------------------- 1 | //! Generated files are imported from here. 2 | //! 3 | //! For the demonstration we generate descriptors twice, with 4 | //! as pure rust codegen, and with codegen dependent on `protoc` binary. 5 | 6 | pub mod generated_with_pure { 7 | include!(concat!(env!("OUT_DIR"), "/generated_with_pure/mod.rs")); 8 | } 9 | 10 | pub mod generated_with_native { 11 | include!(concat!(env!("OUT_DIR"), "/generated_with_native/mod.rs")); 12 | } 13 | -------------------------------------------------------------------------------- /google-protobuf-all-protos/protobuf/protobuf-git/ruby/src/main/sentinel.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | package com.google.protobuf.jruby; 3 | option optimize_for = CODE_SIZE; 4 | 5 | message Sentinel { 6 | int32 default_int32 = 1; 7 | int64 default_int64 = 2; 8 | uint32 default_unit32 = 3; 9 | uint64 default_uint64 = 4; 10 | string default_string = 5; 11 | bool default_bool = 6; 12 | float default_float = 7; 13 | double default_double = 8; 14 | bytes default_bytes = 9; 15 | } 16 | -------------------------------------------------------------------------------- /test-crates/protobuf-codegen-protoc-test/src/common/v2/test_well_known_types_pb.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto2"; 2 | 3 | import "google/protobuf/struct.proto"; 4 | 5 | // generate accessors to make sure accessors are generated correctly 6 | import "rustproto.proto"; 7 | option (rustproto.generate_accessors_all) = true; 8 | 9 | message UsesWellKnownTypes { 10 | optional .google.protobuf.NullValue null_value = 3; 11 | // remaining types are covered by `unittest_well_known_types.proto` 12 | } 13 | -------------------------------------------------------------------------------- /google-protobuf-all-protos/protobuf/protobuf-git/ruby/tests/multi_level_nesting_test.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | message Function { 4 | string name = 1; 5 | repeated Function.Parameter parameters = 2; 6 | string return_type = 3; 7 | 8 | message Parameter { 9 | string name = 1; 10 | Function.Parameter.Value value = 2; 11 | 12 | message Value { 13 | oneof type { 14 | string string = 1; 15 | int64 integer = 2; 16 | } 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /test-crates/protobuf-codegen-protoc-test/src/common/v2/test_reflect_map_pb.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto2"; 2 | 3 | import "rustproto.proto"; 4 | option (rustproto.generate_accessors_all) = true; 5 | 6 | message TestMap { 7 | map map_string_string = 1; 8 | map map_int32_bool = 2; 9 | } 10 | 11 | message TestMapBTreeMap { 12 | map map_string_string = 1; 13 | map map_int32_bool = 2; 14 | option (rustproto.btreemap) = true; 15 | } 16 | -------------------------------------------------------------------------------- /protobuf-examples/customize-serde/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "protobuf-examples-customize" 3 | version = "0.0.0" 4 | authors = ["Stepan Koltsov "] 5 | edition = "2021" 6 | publish = false 7 | 8 | [dependencies] 9 | protobuf = { path = "../../protobuf" } 10 | serde = {version = "1.0.84", features = ["derive"]} 11 | serde_json = "1.0.78" 12 | 13 | [build-dependencies] 14 | protobuf = { path = "../../protobuf" } 15 | protobuf-codegen = { path = "../../protobuf-codegen" } 16 | -------------------------------------------------------------------------------- /protobuf/src/enum_full.rs: -------------------------------------------------------------------------------- 1 | use crate::reflect::EnumDescriptor; 2 | use crate::reflect::EnumValueDescriptor; 3 | use crate::Enum; 4 | 5 | /// Trait is implemented for all enum types if lite runtime is not requested. 6 | /// 7 | /// This trait provides access to runtime reflection. 8 | pub trait EnumFull: Enum { 9 | /// Get enum value descriptor. 10 | fn descriptor(&self) -> EnumValueDescriptor; 11 | 12 | /// Get enum descriptor by type. 13 | fn enum_descriptor() -> EnumDescriptor; 14 | } 15 | -------------------------------------------------------------------------------- /test-crates/protobuf-codegen-protoc-test/src/v2/test_tokio_bytes_default_value_pb.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto2"; 2 | 3 | package test_tokio_bytes_default_value; 4 | 5 | import "rustproto.proto"; 6 | 7 | option (rustproto.tokio_bytes_all) = true; 8 | option (rustproto.tokio_bytes_for_string_all) = true; 9 | option (rustproto.generate_accessors_all) = true; 10 | 11 | message TestTokioBytesDefaultValues { 12 | optional string s = 1 [default = "sss"]; 13 | optional bytes b = 2 [default = "bbb"]; 14 | } 15 | -------------------------------------------------------------------------------- /google-protobuf-all-protos/protobuf/protobuf-git/csharp/protos/unittest_issue6936_c.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | import "unittest_issue6936_a.proto"; 4 | import "unittest_issue6936_b.proto"; 5 | 6 | package unittest_issues; 7 | 8 | option csharp_namespace = "UnitTest.Issues.TestProtos"; 9 | 10 | // This file is used as part of a unit test for issue 6936 11 | // We don't need to use it, we just have to load it at runtime 12 | 13 | message Bar { 14 | option (opt) = "bar"; 15 | Foo foo = 1; 16 | } -------------------------------------------------------------------------------- /protobuf/src/coded_input_stream/input_source.rs: -------------------------------------------------------------------------------- 1 | #[cfg(feature = "bytes")] 2 | use bytes::Bytes; 3 | 4 | use crate::coded_input_stream::buf_read_or_reader::BufReadOrReader; 5 | 6 | /// Hold all possible combinations of input source 7 | #[derive(Debug)] 8 | pub(crate) enum InputSource<'a> { 9 | Read(BufReadOrReader<'a>), 10 | #[allow(dead_code)] // Keep the field to clarify we logically hold the reference. 11 | Slice(&'a [u8]), 12 | #[cfg(feature = "bytes")] 13 | Bytes(&'a Bytes), 14 | } 15 | -------------------------------------------------------------------------------- /test-crates/protobuf-codegen-protoc-test/src/v2/test_reflect_default_pb.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto2"; 2 | 3 | enum Fruit { 4 | APPLE = 1; 5 | BANANA = 2; 6 | } 7 | 8 | message TestReflectDefault { 9 | optional int32 i = 1 [default=10]; 10 | optional string s = 2 [default="sss"]; 11 | optional Fruit e = 3 [default=BANANA]; 12 | 13 | oneof o { 14 | int32 oi = 21 [default=10]; 15 | string os = 22 [default="sss"]; 16 | Fruit oe = 23 [default=BANANA]; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /protobuf-examples/pure-vs-protoc/src/protos/example.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | import "google/protobuf/timestamp.proto"; 4 | 5 | message GetRequest { 6 | string name = 1; 7 | int32 age = 2; 8 | repeated string features = 3; 9 | } 10 | 11 | message GetResponse { 12 | enum Status { 13 | OK = 0; 14 | ERR = 1; 15 | NOT_FOUND = 2; 16 | } 17 | Status status = 1; 18 | string address = 2; 19 | string city = 3; 20 | int32 zipcode = 4; 21 | google.protobuf.Timestamp ts = 5; 22 | } 23 | 24 | -------------------------------------------------------------------------------- /protobuf/src/reflect/acc/v2/mod.rs: -------------------------------------------------------------------------------- 1 | use crate::reflect::acc::v2::map::MapFieldAccessorHolder; 2 | use crate::reflect::acc::v2::repeated::RepeatedFieldAccessorHolder; 3 | use crate::reflect::acc::v2::singular::SingularFieldAccessorHolder; 4 | 5 | pub(crate) mod map; 6 | pub(crate) mod repeated; 7 | pub(crate) mod singular; 8 | 9 | #[derive(Debug)] 10 | pub(crate) enum AccessorV2 { 11 | Singular(SingularFieldAccessorHolder), 12 | Repeated(RepeatedFieldAccessorHolder), 13 | Map(MapFieldAccessorHolder), 14 | } 15 | -------------------------------------------------------------------------------- /google-protobuf-all-protos/protobuf/protobuf-git/php/tests/proto/test_empty_php_namespace.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package foo; 4 | option php_namespace = ""; 5 | option php_metadata_namespace = ""; 6 | 7 | message TestEmptyNamespace { 8 | int32 a = 1; 9 | 10 | // Test nested messages, enums, and reserved names 11 | NestedMessage nested_message = 2; 12 | NestedEnum nested_enum = 3; 13 | message NestedMessage { 14 | int32 a = 1; 15 | } 16 | enum NestedEnum { 17 | ZERO = 0; 18 | }; 19 | } 20 | -------------------------------------------------------------------------------- /test-crates/protobuf-codegen-protoc-test/src/common/v2/test_service.rs: -------------------------------------------------------------------------------- 1 | use super::test_service_pb::*; 2 | 3 | #[test] 4 | fn test_service() { 5 | // The request/response types should still 6 | // get generated, even though we ignore the 7 | // service definition in the same file. 8 | let _ = Request::new(); 9 | let _ = Response::new(); 10 | } 11 | 12 | #[test] 13 | fn reflect() { 14 | let services = file_descriptor().services().collect::>(); 15 | assert_eq!(1, services.len()); 16 | } 17 | -------------------------------------------------------------------------------- /test-crates/protobuf-codegen-protoc-test/src/v2/test_tokio_bytes_default_value.rs: -------------------------------------------------------------------------------- 1 | use protobuf::*; 2 | 3 | use super::test_tokio_bytes_default_value_pb::*; 4 | 5 | #[test] 6 | fn test_default_values() { 7 | assert_eq!("sss", TestTokioBytesDefaultValues::default_instance().s()); 8 | assert_eq!(b"bbb", TestTokioBytesDefaultValues::default_instance().b()); 9 | assert_eq!(&""[..], &**TestTokioBytesDefaultValues::new().mut_s()); 10 | assert_eq!(&b""[..], &**TestTokioBytesDefaultValues::new().mut_b()); 11 | } 12 | -------------------------------------------------------------------------------- /test-crates/protobuf-test/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "protobuf-test" 3 | version = "0.0.0" 4 | authors = ["Stepan Koltsov "] 5 | publish = false 6 | edition = "2021" 7 | description = """ 8 | Common code of protobuf tests 9 | """ 10 | 11 | [lib] 12 | doctest = false 13 | bench = false 14 | 15 | [dependencies] 16 | regex = "1.5.5" 17 | 18 | protobuf = { path = "../../protobuf" } 19 | protobuf-parse = { path = "../../protobuf-parse" } 20 | 21 | protobuf-test-common = { path = "../protobuf-test-common" } 22 | -------------------------------------------------------------------------------- /test-crates/protobuf-codegen-protoc-test/src/common/v2/test_oneof_nonexhaustive.rs: -------------------------------------------------------------------------------- 1 | use protobuf::OneofFull; 2 | use protobuf_test_common::*; 3 | 4 | use super::test_oneof_nonexhaustive_pb::*; 5 | 6 | #[test] 7 | fn test_oneof_nonexhaustive_disabled() { 8 | use message_with_oneof_nonexhaustive_disabled::One; 9 | match MessageWithOneofNonexhaustiveDisabled::default().one { 10 | None => (), 11 | Some(one) => match one { 12 | One::FirstField(_) | One::SecondField(_) => (), 13 | }, 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /google-protobuf-all-protos/protobuf/protobuf-git/csharp/protos/unittest_issue6936_a.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package unittest_issues; 4 | 5 | option csharp_namespace = "UnitTest.Issues.TestProtos"; 6 | 7 | // This file is used as part of a unit test for issue 6936 8 | // We don't need to use it, we just have to import it in both 9 | // "extensions_issue6936_b.proto" and "extensions_issue6936_c.proto" 10 | 11 | import "google/protobuf/descriptor.proto"; 12 | 13 | extend google.protobuf.MessageOptions { 14 | string opt = 50000; 15 | } -------------------------------------------------------------------------------- /google-protobuf-all-protos/protobuf/protobuf-git/php/tests/proto/test_no_namespace.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | option php_metadata_namespace = "\\"; 4 | 5 | message NoNamespaceMessage { 6 | int32 a = 1; 7 | 8 | // Test nested messages, enums, and reserved names 9 | NestedMessage nested_message = 2; 10 | NestedEnum nested_enum = 3; 11 | message NestedMessage { 12 | int32 a = 1; 13 | } 14 | enum NestedEnum { 15 | ZERO = 0; 16 | }; 17 | } 18 | 19 | enum NoNamespaceEnum { 20 | VALUE_A = 0; 21 | VALUE_B = 1; 22 | } 23 | -------------------------------------------------------------------------------- /test-crates/protobuf-codegen-protoc-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 | 12 | message RecursiveA { 13 | oneof x { 14 | RecursiveB b = 1; 15 | } 16 | } 17 | 18 | message RecursiveB { 19 | oneof x { 20 | RecursiveC c = 1; 21 | } 22 | } 23 | 24 | message RecursiveC { 25 | oneof x { 26 | RecursiveA a = 1; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /test-crates/protobuf-codegen-protoc-test/src/common/v2/test_tokio_bytes_pb.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto2"; 2 | 3 | import "rustproto.proto"; 4 | 5 | option (rustproto.tokio_bytes_all) = true; 6 | option (rustproto.tokio_bytes_for_string_all) = true; 7 | option (rustproto.generate_accessors_all) = true; 8 | 9 | message TestTokioBytes { 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 | -------------------------------------------------------------------------------- /test-crates/protobuf-parse-error-test/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "protobuf-parse-error-test" 3 | version = "0.0.0" 4 | authors = ["Stepan Koltsov "] 5 | publish = false 6 | edition = "2021" 7 | 8 | [lib] 9 | doctest = false 10 | bench = false 11 | 12 | [dependencies] 13 | tempfile = "3.2.0" 14 | 15 | protoc-bin-vendored = { workspace = true } 16 | 17 | protobuf-parse = { path = "../../protobuf-parse" } 18 | protobuf-test-common = { path = "../../test-crates/protobuf-test-common" } 19 | protobuf = { path = "../../protobuf" } 20 | -------------------------------------------------------------------------------- /test-crates/protobuf-codegen-protoc-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 | 17 | message TestPackedDefault { 18 | repeated uint32 varints = 1; 19 | } 20 | -------------------------------------------------------------------------------- /protobuf/src/well_known_types/mod.rs: -------------------------------------------------------------------------------- 1 | // This file is generated. Do not edit 2 | // @generated 3 | //! Generated code for "well known types" 4 | //! 5 | //! [This document](https://developers.google.com/protocol-buffers/docs/reference/google.protobuf) describes these types. 6 | 7 | #![allow(unused_attributes)] 8 | #![cfg_attr(rustfmt, rustfmt::skip)] 9 | 10 | pub mod any; 11 | pub mod api; 12 | pub mod duration; 13 | pub mod empty; 14 | pub mod field_mask; 15 | pub mod source_context; 16 | pub mod struct_; 17 | pub mod timestamp; 18 | pub mod type_; 19 | pub mod wrappers; 20 | -------------------------------------------------------------------------------- /test-crates/perftest/bytes/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "perftest-bytes" 3 | version = "0.0.0" 4 | authors = ["Stepan Koltsov "] 5 | publish = false 6 | edition = "2021" 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 = "1.1", optional = true } 18 | 19 | [dependencies.protobuf] 20 | path = "../../../protobuf" 21 | 22 | [build-dependencies] 23 | protobuf-codegen = { path = "../../../protobuf-codegen" } 24 | -------------------------------------------------------------------------------- /protobuf-codegen/src/gen/map.rs: -------------------------------------------------------------------------------- 1 | use crate::gen::scope::FieldWithContext; 2 | use crate::gen::scope::MessageWithScope; 3 | 4 | /// Pair of (key, value) if this message is map entry 5 | pub(crate) fn map_entry<'a>( 6 | d: &'a MessageWithScope, 7 | ) -> Option<(FieldWithContext<'a>, FieldWithContext<'a>)> { 8 | if d.message.is_map_entry() { 9 | // `MessageDescriptor` validated the fields. 10 | let key = d.fields()[0].clone(); 11 | let value = d.fields()[1].clone(); 12 | Some((key, value)) 13 | } else { 14 | None 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /protoc-bin/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "protoc-bin" 3 | version = "0.0.0" 4 | authors = ["Stepan Koltsov "] 5 | license = "MIT" 6 | homepage = "https://github.com/stepancheg/rust-protobuf/" 7 | repository = "https://github.com/stepancheg/rust-protobuf/" 8 | description = """ 9 | Internal crate to rust-protobuf 10 | """ 11 | publish = false 12 | edition = "2021" 13 | 14 | [lib] 15 | doctest = false 16 | bench = false 17 | 18 | [dependencies] 19 | protoc-bin-vendored = { workspace = true } 20 | 21 | [package.metadata.docs.rs] 22 | all-features = true 23 | -------------------------------------------------------------------------------- /test-crates/interop/cxx/compile.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -ex 4 | 5 | cd $(dirname $0) 6 | 7 | if test -n "$PROTOBUF_PREFIX"; then 8 | if test -n "$PKG_CONFIG_PATH"; then 9 | PKG_CONFIG_PATH=":$PKG_CONFIG_PATH" 10 | fi 11 | export PKG_CONFIG_PATH="$PROTOBUF_PREFIX/lib/pkgconfig$PKG_CONFIG_PATH" 12 | fi 13 | 14 | protoc --cpp_out=. interop_pb.proto 15 | c++ --version 16 | c++ -std=c++11 -Wall -O1 \ 17 | interop.cc interop_pb.pb.cc \ 18 | `pkg-config --cflags --libs protobuf` \ 19 | -o interop 20 | ./interop self-test 21 | 22 | # vim: set ts=4 sw=4 et: 23 | -------------------------------------------------------------------------------- /protobuf/src/rt/repeated.rs: -------------------------------------------------------------------------------- 1 | use crate::CodedInputStream; 2 | use crate::Enum; 3 | use crate::EnumOrUnknown; 4 | 5 | /// Read repeated enum field when the wire format is length-delimited. 6 | pub fn read_repeated_packed_enum_or_unknown_into( 7 | is: &mut CodedInputStream, 8 | target: &mut Vec>, 9 | ) -> crate::Result<()> { 10 | let len = is.read_raw_varint64()?; 11 | let old_limit = is.push_limit(len)?; 12 | while !is.eof()? { 13 | target.push(is.read_enum_or_unknown()?); 14 | } 15 | is.pop_limit(old_limit); 16 | Ok(()) 17 | } 18 | -------------------------------------------------------------------------------- /BUGREPORTING.md: -------------------------------------------------------------------------------- 1 | # How to report bugs 2 | 3 | When you report a bug, please always specify: 4 | 5 | * which version of protobuf library do you use 6 | * which of three ways to generate source code do you use 7 | * which operating system you are on 8 | * if you use some features, please specify these features 9 | * if the generated code is incorrect, please provide both `.proto` input and generated output 10 | and codegen options if you have specified any. 11 | 12 | Ideally, please create a small github project, which can be used to reproduce a problem with single command. 13 | 14 | Thanks! 15 | -------------------------------------------------------------------------------- /proto/update.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # Update bundled .proto files 4 | 5 | set -ex 6 | 7 | cd "$(dirname $0)" 8 | 9 | cargo build --manifest-path=../protoc-bin/Cargo.toml --bin protoc-bin-print-paths 10 | 11 | eval "$(cargo run --manifest-path=../protoc-bin/Cargo.toml --bin protoc-bin-print-paths)" 12 | 13 | test -n "$PROTOC" 14 | test -n "$PROTOBUF_INCLUDE" 15 | 16 | 17 | rm -rf google 18 | cp -r "$PROTOBUF_INCLUDE/google" google 19 | 20 | cp -r "$PROTOBUF_INCLUDE/google" ../protobuf-parse/src/proto/ 21 | cp -r "rustproto.proto" ../protobuf-parse/src/proto/ 22 | 23 | # vim: set ts=4 sw=4 et: 24 | -------------------------------------------------------------------------------- /protobuf-examples/issue-614/examples/example-issue-614.rs: -------------------------------------------------------------------------------- 1 | use protobuf::MessageFull; 2 | use protobuf_examples_issue_614::foos; 3 | use protobuf_examples_issue_614::generate_insert; 4 | use protobuf_examples_issue_614::generate_schema_for; 5 | 6 | fn main() { 7 | let descriptor = protobuf_examples_issue_614::foos::Foo::descriptor(); 8 | println!("Schema: {}", generate_schema_for(descriptor)); 9 | 10 | let mut message = foos::Foo::new(); 11 | message.bar = 1; 12 | message.baz = Some(foos::foo::Baz::Qux("test".to_owned())); 13 | println!("Insert: {}", generate_insert(&message)); 14 | } 15 | -------------------------------------------------------------------------------- /test-crates/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 = "2021" 7 | 8 | [features] 9 | default = [] 10 | proto3 = [] 11 | with-bytes = ["protobuf/with-bytes"] 12 | 13 | [dependencies.protobuf] 14 | path = "../../../protobuf" 15 | 16 | [dependencies] 17 | rand = "~0.5" 18 | 19 | [build-dependencies] 20 | protobuf-codegen = { path = "../../../protobuf-codegen" } 21 | 22 | [[bin]] 23 | 24 | name = "rust-protobuf-perftest" 25 | path = "perftest.rs" 26 | test = false 27 | -------------------------------------------------------------------------------- /protobuf-examples/README.md: -------------------------------------------------------------------------------- 1 | # rust-protobuf examples 2 | 3 | This directory contains examples for rust-protobuf version 3. 4 | 5 | Rust-protobuf 3 is currently alpha version, and will be released 6 | in a few weeks. 7 | 8 | Rust-protobuf version 2 has similar API, but examples won't work 9 | as is with version 2. 10 | 11 | ## Crate references 12 | 13 | In the examples, protobuf crates are referenced by relative paths: 14 | 15 | ```toml 16 | protobuf = { path = "../../protobuf" } 17 | ``` 18 | 19 | in your project versions should be used instead like: 20 | 21 | ```toml 22 | protobuf = "3.0.0-alpha.8" 23 | ``` 24 | -------------------------------------------------------------------------------- /protobuf-support/src/json_name.rs: -------------------------------------------------------------------------------- 1 | /// Implementation must match exactly 2 | /// `ToJsonName()` function in C++ `descriptor.cc`. 3 | pub 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 | -------------------------------------------------------------------------------- /test-crates/protobuf-codegen-protoc-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 | -------------------------------------------------------------------------------- /protobuf/src/lazy.rs: -------------------------------------------------------------------------------- 1 | use once_cell::sync::OnceCell; 2 | 3 | /// Lazily initialized static variable. 4 | /// 5 | /// Used in generated code. 6 | /// 7 | /// Currently a wrapper around `once_cell`s `OnceCell`. 8 | pub struct Lazy { 9 | once_cell: OnceCell, 10 | } 11 | 12 | impl Lazy { 13 | /// Uninitialized state. 14 | pub const fn new() -> Lazy { 15 | Lazy { 16 | once_cell: OnceCell::new(), 17 | } 18 | } 19 | 20 | /// Lazily initialize the value. 21 | pub fn get(&self, f: impl FnOnce() -> T) -> &T { 22 | self.once_cell.get_or_init(f) 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /protobuf-codegen/src/gen/mod.rs: -------------------------------------------------------------------------------- 1 | pub(crate) mod all; 2 | pub(crate) mod code_writer; 3 | pub(crate) mod descriptor; 4 | pub(crate) mod enums; 5 | pub(crate) mod extensions; 6 | pub(crate) mod field; 7 | pub(crate) mod file; 8 | pub(crate) mod file_and_mod; 9 | pub(crate) mod file_descriptor; 10 | pub(crate) mod inside; 11 | mod map; 12 | pub(crate) mod message; 13 | pub(crate) mod mod_rs; 14 | pub(crate) mod oneof; 15 | pub(crate) mod paths; 16 | pub(crate) mod protoc_insertion_point; 17 | pub(crate) mod rust; 18 | pub(crate) mod rust_types_values; 19 | pub(crate) mod scope; 20 | pub(crate) mod strx; 21 | pub(crate) mod well_known_types; 22 | -------------------------------------------------------------------------------- /test-crates/perftest/misc/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "protobuf-perftest-misc" 3 | version = "0.0.0" 4 | authors = ["Stepan Koltsov "] 5 | publish = false 6 | edition = "2021" 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 = "1.1", optional = true } 18 | fastrand = "1.4.0" 19 | 20 | [dependencies.protobuf] 21 | path = "../../../protobuf" 22 | features = ["with-bytes"] 23 | 24 | [build-dependencies] 25 | protobuf-codegen = { path = "../../../protobuf-codegen" } 26 | -------------------------------------------------------------------------------- /protobuf-examples/customize-serde/README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # How to use serde with rust-protobuf 4 | 5 | rust-protobuf 3 no longer directly supports serde. 6 | 7 | Practically, serde is needed mostly to be able to serialize and deserialize JSON, 8 | and **rust-protobuf supports JSON directly**, and more correctly according to 9 | official protobuf to JSON mapping. For that reason, 10 | native serde support was removed from rust-protobuf. 11 | 12 | This crate is an example how to inject serde annotations into generated code. 13 | 14 | Annotations are configured from `build.rs`. 15 | 16 | 17 | -------------------------------------------------------------------------------- /protobuf-parse/README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Parse `.proto` files 4 | 5 | Parse `.proto` file definitions, **not** the protobuf text format serialization. 6 | 7 | Files can be parsed using pure Rust parser (mod `pure`) 8 | or using the `protoc` command (mod `protoc`). 9 | 10 | This crate is not meant to be used directly, but rather through the `protobuf-codegen` crate. 11 | If you think this crate might be useful to you, 12 | please [consider creating an issue](https://github.com/stepancheg/rust-protobuf/issues/new), 13 | until that this crate is considered to have **no stable API**. 14 | 15 | 16 | -------------------------------------------------------------------------------- /test-crates/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.tokio_bytes) = true; 16 | option (rustproto.tokio_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-codegen/src/gen/mod_rs.rs: -------------------------------------------------------------------------------- 1 | use crate::compiler_plugin; 2 | use crate::gen::code_writer::CodeWriter; 3 | 4 | pub(crate) fn gen_mod_rs(mods: &[String]) -> compiler_plugin::GenResult { 5 | let v = CodeWriter::with_no_error(|w| { 6 | w.comment(&format!("{}generated", "@")); 7 | w.write_line(""); 8 | let mut mods: Vec<&String> = mods.into_iter().collect(); 9 | mods.sort(); 10 | for m in mods { 11 | w.write_line(&format!("pub mod {};", m)); 12 | } 13 | }); 14 | compiler_plugin::GenResult { 15 | name: "mod.rs".to_owned(), 16 | content: v.into_bytes(), 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /protobuf-examples/pure-vs-protoc/README.md: -------------------------------------------------------------------------------- 1 | # rust-protobuf-example 2 | 3 | Example rust protobuf project 4 | 5 | (This is an example for the master branch. For protobuf=v2.19 look at the 6 | [same directory in v2.19 branch](https://github.com/stepancheg/rust-protobuf/tree/v2.19/protobuf-examples).) 7 | 8 | ## Motivation 9 | 10 | Simple and obvious examples for using `rust-protobuf` module were lacking, so this was created. 11 | 12 | ## Look here 13 | 14 | Key files to read are: 15 | 16 | * src/protos/example.proto 17 | * src/main.rs 18 | * build.rs 19 | 20 | ## Using 21 | 22 | Standard rust package: 23 | ``` 24 | $ cargo build 25 | $ cargo run 26 | ``` 27 | -------------------------------------------------------------------------------- /test-crates/protobuf-codegen-protoc-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 protobuf_test_common::*; 4 | 5 | use super::test_singular_concat_pb::*; 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-codegen/src/protoc_gen_rs.rs: -------------------------------------------------------------------------------- 1 | #![doc(hidden)] 2 | 3 | use crate::compiler_plugin; 4 | use crate::customize::CustomizeCallbackDefault; 5 | use crate::gen::all::gen_all; 6 | use crate::Customize; 7 | 8 | #[doc(hidden)] 9 | pub fn protoc_gen_rust_main() { 10 | compiler_plugin::plugin_main(|r| { 11 | let customize = Customize::parse_from_parameter(r.parameter).expect("parse options"); 12 | gen_all( 13 | r.file_descriptors, 14 | "protoc --rs_out=...", 15 | r.files_to_generate, 16 | &customize, 17 | &CustomizeCallbackDefault, 18 | ) 19 | }) 20 | .expect("plugin failed"); 21 | } 22 | -------------------------------------------------------------------------------- /protobuf-support/src/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, Ord, PartialOrd)] 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 | -------------------------------------------------------------------------------- /test-crates/protobuf-codegen-protoc-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 | -------------------------------------------------------------------------------- /test-crates/protobuf-codegen-protoc-test/src/common/v2/test_tokio_bytes.rs: -------------------------------------------------------------------------------- 1 | use bytes::Bytes; 2 | use protobuf::Chars; 3 | use protobuf_test_common::*; 4 | 5 | use super::test_tokio_bytes_pb::*; 6 | 7 | #[test] 8 | fn test() { 9 | let mut m = TestTokioBytes::new(); 10 | m.set_b1(Bytes::from("aabb")); 11 | m.set_s1(Chars::from("ccdd")); 12 | 13 | let mut br = Vec::new(); 14 | br.push(Bytes::from("bb1")); 15 | br.push(Bytes::from("bb2")); 16 | m.set_br(br); 17 | 18 | let mut sr = Vec::new(); 19 | sr.push(Chars::from("ss1")); 20 | sr.push(Chars::from("ss2")); 21 | m.set_sr(sr); 22 | 23 | test_serialize_deserialize_no_hex_with_dynamic(&m); 24 | } 25 | -------------------------------------------------------------------------------- /test-crates/protobuf-test-common/src/cargo.rs: -------------------------------------------------------------------------------- 1 | //! Emit instructions to cargo. 2 | 3 | use std::fs; 4 | use std::path::Path; 5 | 6 | fn print_rerun_if_changed>(path: P) { 7 | let path = path.as_ref(); 8 | println!("cargo:rerun-if-changed={}", path.to_str().expect("to_str")); 9 | } 10 | 11 | pub fn print_rerun_if_changed_recursively>(path: P) { 12 | let path = path.as_ref(); 13 | print_rerun_if_changed(path); 14 | if path.is_dir() { 15 | for child in fs::read_dir(path).expect("read_dir") { 16 | let child = child.expect("child").path(); 17 | print_rerun_if_changed_recursively(child); 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /protobuf-support/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | 3 | name = "protobuf-support" 4 | version = "4.0.0-alpha.0" 5 | authors = ["Stepan Koltsov "] 6 | edition = "2021" 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 | Code supporting protobuf implementation. None of code in this crate is public API. 13 | """ 14 | 15 | [lib] 16 | bench = false 17 | 18 | [features] 19 | 20 | [dependencies] 21 | thiserror = "1.0.30" 22 | 23 | [package.metadata.docs.rs] 24 | all-features = true 25 | -------------------------------------------------------------------------------- /protobuf/src/reflect/repeated/transmute.rs: -------------------------------------------------------------------------------- 1 | use std::any::TypeId; 2 | 3 | pub(crate) fn transmute_mut_if_eq(a: &mut A) -> Result<&mut B, &mut A> { 4 | if TypeId::of::() == TypeId::of::() { 5 | // SAFETY: we check type before transmuting. 6 | Ok(unsafe { &mut *(a as *mut A as *mut B) }) 7 | } else { 8 | Err(a) 9 | } 10 | } 11 | 12 | pub(crate) fn transmute_ref_if_eq(a: &A) -> Result<&B, &A> { 13 | if TypeId::of::() == TypeId::of::() { 14 | // SAFETY: we check type before transmuting. 15 | Ok(unsafe { &*(a as *const A as *const B) }) 16 | } else { 17 | Err(a) 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /test-crates/protobuf-codegen-protoc-test/src/v2/test_required.rs: -------------------------------------------------------------------------------- 1 | use protobuf::Message; 2 | 3 | use super::test_required_pb::*; 4 | 5 | #[test] 6 | fn test_write_missing_required() { 7 | assert!(TestRequired::new().write_to_bytes().is_err()); 8 | } 9 | 10 | #[test] 11 | fn test_read_missing_required() { 12 | assert!(TestRequired::parse_from_bytes(&[]).is_err()); 13 | } 14 | 15 | #[test] 16 | fn test_is_initialized_is_recursive() { 17 | let mut m = TestRequiredOuter::new(); 18 | assert!(!m.is_initialized()); 19 | m.inner = Some(Default::default()).into(); 20 | assert!(!m.is_initialized()); 21 | m.inner.as_mut().unwrap().set_b(false); 22 | assert!(m.is_initialized()); 23 | } 24 | -------------------------------------------------------------------------------- /test-crates/protobuf-codegen-protoc-test/src/common/v2/test_enum_unknown_values_preserved.rs: -------------------------------------------------------------------------------- 1 | use protobuf::Message; 2 | use protobuf_test_common::*; 3 | 4 | use super::test_enum_unknown_values_preserved_pb::*; 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_with_dynamic("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 = OldMessage::parse_from_bytes(&hex::decode_hex("08 1e")).expect("parse"); 17 | 18 | test_serialize_deserialize_with_dynamic("08 1e", &old); 19 | } 20 | -------------------------------------------------------------------------------- /protobuf/src/reflect/file/syntax.rs: -------------------------------------------------------------------------------- 1 | use crate::descriptor::FileDescriptorProto; 2 | 3 | /// `.proto` file syntax. 4 | #[derive(Debug, Copy, Clone, PartialEq, Eq)] 5 | pub enum Syntax { 6 | /// `syntax = "proto2"`. 7 | Proto2, 8 | /// `syntax = "proto3"`. 9 | Proto3, 10 | } 11 | 12 | impl Syntax { 13 | pub(crate) fn parse(syntax: &str) -> Option { 14 | match syntax { 15 | "" | "proto2" => Some(Syntax::Proto2), 16 | "proto3" => Some(Syntax::Proto3), 17 | _ => None, 18 | } 19 | } 20 | 21 | pub(crate) fn of_file(file: &FileDescriptorProto) -> Syntax { 22 | Syntax::parse(file.syntax()).unwrap_or(Syntax::Proto2) 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /test-crates/protobuf-test-common/src/lib.rs: -------------------------------------------------------------------------------- 1 | //! Random code uses in protobuf test crates. 2 | 3 | pub mod build; 4 | pub mod hex; 5 | 6 | mod serialize_deserialize_generated; 7 | pub use serialize_deserialize_generated::*; 8 | 9 | mod serialize_deserialize_dynamic; 10 | pub use serialize_deserialize_dynamic::*; 11 | 12 | mod serialize_deserialize_both; 13 | pub use serialize_deserialize_both::*; 14 | 15 | mod text_format_tests; 16 | pub use text_format_tests::*; 17 | 18 | mod json_tests; 19 | pub use json_tests::*; 20 | 21 | mod reflect_tests; 22 | pub use reflect_tests::*; 23 | 24 | mod cargo; 25 | pub use cargo::*; 26 | 27 | mod interop; 28 | pub use interop::*; 29 | 30 | mod dynamic; 31 | pub use dynamic::*; 32 | -------------------------------------------------------------------------------- /test-crates/protobuf-test-common/src/serialize_deserialize_both.rs: -------------------------------------------------------------------------------- 1 | use protobuf::MessageFull; 2 | 3 | use crate::serialize_then_parse_as_dynamic_and_serialize_and_parse; 4 | use crate::serialize_then_parse_as_dynamic_then_serialize; 5 | use crate::test_serialize_deserialize; 6 | use crate::test_serialize_deserialize_no_hex; 7 | 8 | pub fn test_serialize_deserialize_no_hex_with_dynamic(m: &M) { 9 | test_serialize_deserialize_no_hex(m); 10 | serialize_then_parse_as_dynamic_and_serialize_and_parse(m); 11 | } 12 | 13 | pub fn test_serialize_deserialize_with_dynamic(hex: &str, m: &M) { 14 | test_serialize_deserialize(hex, m); 15 | serialize_then_parse_as_dynamic_then_serialize(m); 16 | } 17 | -------------------------------------------------------------------------------- /google-protobuf-all-protos/protobuf/protobuf-git/php/tests/proto/test_descriptors.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package descriptors; 4 | 5 | message TestDescriptorsMessage { 6 | int32 optional_int32 = 1; 7 | TestDescriptorsEnum optional_enum = 16; 8 | Sub optional_message = 17; 9 | 10 | // Repeated 11 | repeated int32 repeated_int32 = 31; 12 | repeated Sub repeated_message = 47; 13 | 14 | oneof my_oneof { 15 | int32 oneof_int32 = 51; 16 | } 17 | 18 | map map_int32_enum = 71; 19 | 20 | message Sub { 21 | int32 a = 1; 22 | repeated int32 b = 2; 23 | } 24 | 25 | enum EnumSub { 26 | ZERO = 0; 27 | ONE = 1; 28 | } 29 | } 30 | 31 | enum TestDescriptorsEnum { 32 | ZERO = 0; 33 | ONE = 1; 34 | } 35 | 36 | -------------------------------------------------------------------------------- /protobuf/src/fixed.rs: -------------------------------------------------------------------------------- 1 | /// Fixed size integers. 2 | pub(crate) trait ProtobufFixed { 3 | /// Size of this fixed type in bytes. 4 | const LEN: u32; 5 | } 6 | 7 | impl ProtobufFixed for u32 { 8 | const LEN: u32 = 4; 9 | } 10 | 11 | impl ProtobufFixed for i32 { 12 | const LEN: u32 = 4; 13 | } 14 | 15 | impl ProtobufFixed for u64 { 16 | const LEN: u32 = 8; 17 | } 18 | 19 | impl ProtobufFixed for i64 { 20 | const LEN: u32 = 8; 21 | } 22 | 23 | impl ProtobufFixed for f32 { 24 | const LEN: u32 = 4; 25 | } 26 | 27 | impl ProtobufFixed for f64 { 28 | const LEN: u32 = 8; 29 | } 30 | 31 | /// Technically `bool` is not fixed, but it can be considered as fixed 32 | /// for the purpose of encoding. 33 | impl ProtobufFixed for bool { 34 | const LEN: u32 = 1; 35 | } 36 | -------------------------------------------------------------------------------- /ci-gen/src/install_protobuf.rs: -------------------------------------------------------------------------------- 1 | use crate::actions::cache; 2 | use crate::ghwf::Step; 3 | use crate::Os; 4 | use crate::MACOS; 5 | 6 | pub(crate) fn install_protobuf(os: Os) -> Vec { 7 | let protobuf_version = "3.19.4"; 8 | 9 | let mut steps = Vec::new(); 10 | steps.push(cache( 11 | "Cache protobuf", 12 | &format!("pb-{}-{}", os.name, protobuf_version), 13 | "~/pb", 14 | )); 15 | 16 | if os == MACOS { 17 | steps.push(Step::run("Install pkg-config", "brew install pkg-config")); 18 | } 19 | 20 | steps.push( 21 | Step::run("Install protobuf", "ci/install-protobuf.sh") 22 | .env("PROTOBUF_VERSION", protobuf_version), 23 | ); 24 | steps.push(Step::run("Protoc check", "protoc --version")); 25 | steps 26 | } 27 | -------------------------------------------------------------------------------- /protobuf-parse/src/path.rs: -------------------------------------------------------------------------------- 1 | use std::path::is_separator; 2 | 3 | use crate::proto_path::ProtoPath; 4 | 5 | pub(crate) fn fs_path_to_proto_path(path: &ProtoPath) -> String { 6 | path.to_str() 7 | .chars() 8 | .map(|c| if is_separator(c) { '/' } else { c }) 9 | .collect() 10 | } 11 | 12 | #[cfg(test)] 13 | mod test { 14 | use crate::path::fs_path_to_proto_path; 15 | use crate::ProtoPath; 16 | 17 | #[test] 18 | fn test_fs_path_to_proto_path() { 19 | assert_eq!( 20 | "foo.proto", 21 | fs_path_to_proto_path(ProtoPath::new("foo.proto").unwrap()) 22 | ); 23 | assert_eq!( 24 | "bar/foo.proto", 25 | fs_path_to_proto_path(ProtoPath::new("bar/foo.proto").unwrap()) 26 | ); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /test-crates/protobuf-codegen-protoc-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 | -------------------------------------------------------------------------------- /test-crates/protobuf-codegen-protoc-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 TestMapBTreeMap { 17 | map m = 1; 18 | map mm = 2; 19 | // just check it compiles 20 | map me = 3; 21 | option (rustproto.btreemap) = true; 22 | } 23 | 24 | message TestMapEntry { 25 | optional int64 v = 1; 26 | } 27 | 28 | enum TestMapEnum { 29 | UNKNOWN = 0; 30 | ONE = 1; 31 | } 32 | -------------------------------------------------------------------------------- /protobuf-json-mapping/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | 3 | name = "protobuf-json-mapping" 4 | version = "4.0.0-alpha.0" 5 | authors = ["Stepan Koltsov "] 6 | edition = "2021" 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 | JSON mapping for Protocol Buffers messages. 13 | """ 14 | 15 | [lib] 16 | bench = false 17 | 18 | [dependencies] 19 | thiserror = "1.0.30" 20 | 21 | protobuf = { path = "../protobuf", version = "=4.0.0-alpha.0" } 22 | protobuf-support = { path = "../protobuf-support", version = "=4.0.0-alpha.0" } 23 | 24 | [package.metadata.docs.rs] 25 | all-features = true 26 | -------------------------------------------------------------------------------- /test-crates/protobuf-codegen-identical-test/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "protobuf-codegen-identical-test" 3 | version = "0.0.0" 4 | authors = ["Nikhil Benesch "] 5 | publish = false 6 | edition = "2021" 7 | description = "Test protoc-based and pure rust codegen produce identical output" 8 | 9 | [lib] 10 | test = false 11 | doctest = false 12 | 13 | [dev-dependencies] 14 | anyhow = "1.0.57" 15 | tempfile = "3" 16 | regex = "1.3.9" 17 | 18 | protoc-bin-vendored = { workspace = true } 19 | 20 | protobuf = { path = "../../protobuf" } 21 | protobuf-support = { path = "../../protobuf-support" } 22 | protobuf-codegen = { path = "../../protobuf-codegen" } 23 | protobuf-test-common = { path = "../../test-crates/protobuf-test-common" } 24 | protobuf-parse = { path = "../../protobuf-parse" } 25 | -------------------------------------------------------------------------------- /test-crates/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 = "2021" 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 | 20 | [dependencies] 21 | anyhow = "1.0.53" 22 | glob = "0.2" 23 | log = "0.4" 24 | env_logger = "0.5.*" 25 | tempfile = "3.0" 26 | bytes = { version = "1.1", optional = true } 27 | 28 | protobuf = { path = "../../protobuf" } 29 | protobuf-json-mapping = { path = "../../protobuf-json-mapping" } 30 | protobuf-codegen = { path = "../../protobuf-codegen" } 31 | -------------------------------------------------------------------------------- /test-crates/protobuf-codegen-protoc-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 | -------------------------------------------------------------------------------- /google-protobuf-all-protos/protobuf/protobuf-git/php/tests/proto/test_php_namespace.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package foo; 4 | option php_namespace = "Php\\Test"; 5 | option php_metadata_namespace = "Metadata\\Php\\Test"; 6 | 7 | message TestNamespace { 8 | int32 a = 1; 9 | 10 | // Test nested messages, enums, and reserved names 11 | NestedMessage nested_message = 2; 12 | NestedEnum nested_enum = 3; 13 | Empty reserved_name = 4; 14 | message NestedMessage { 15 | int32 a = 1; 16 | } 17 | enum NestedEnum { 18 | ZERO = 0; 19 | }; 20 | // Test reserved name 21 | message Empty { 22 | NestedMessage nested_message = 1; 23 | NestedEnum nested_enum = 2; 24 | message NestedMessage { 25 | int32 a = 1; 26 | } 27 | enum NestedEnum { 28 | ZERO = 0; 29 | }; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /test-crates/perftest/misc/benches/write.rs: -------------------------------------------------------------------------------- 1 | // `cargo test --benches` and `#[feature(test)]` work only in nightly 2 | #![cfg(rustc_nightly)] 3 | #![feature(test)] 4 | 5 | extern crate test; 6 | 7 | use protobuf::well_known_types::struct_::value; 8 | use protobuf::well_known_types::struct_::Struct; 9 | use protobuf::well_known_types::struct_::Value; 10 | use protobuf::Message; 11 | use test::Bencher; 12 | 13 | #[bench] 14 | fn write_to_bytes(b: &mut Bencher) { 15 | let mut value = Value::new(); 16 | value.kind = Some(value::Kind::NumberValue(10.0)); 17 | let mut value2 = Value::new(); 18 | value2.kind = Some(value::Kind::BoolValue(true)); 19 | let mut s = Struct::new(); 20 | s.fields.insert("foo".to_owned(), value); 21 | s.fields.insert("bar".to_owned(), value2); 22 | b.iter(|| s.write_to_bytes()); 23 | } 24 | -------------------------------------------------------------------------------- /protobuf-json-mapping/src/lib.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 parse; 7 | mod print; 8 | mod rfc_3339; 9 | mod well_known_wrapper; 10 | 11 | pub use self::parse::merge_from_str; 12 | pub use self::parse::merge_from_str_with_options; 13 | pub use self::parse::parse_dyn_from_str; 14 | pub use self::parse::parse_dyn_from_str_with_options; 15 | pub use self::parse::parse_from_str; 16 | pub use self::parse::parse_from_str_with_options; 17 | pub use self::parse::ParseError; 18 | pub use self::parse::ParseOptions; 19 | pub use self::print::print_to_string; 20 | pub use self::print::print_to_string_with_options; 21 | pub use self::print::PrintError; 22 | pub use self::print::PrintOptions; 23 | -------------------------------------------------------------------------------- /test-crates/protobuf-codegen-protoc-test/src/interop/bin.rs: -------------------------------------------------------------------------------- 1 | use protobuf::Message; 2 | use protobuf_test_common::hex::encode_hex; 3 | use protobuf_test_common::interop_json_decode; 4 | 5 | use super::interop_pb::InteropMessageList; 6 | use crate::interop::interop_pb::InteropMessage; 7 | 8 | #[test] 9 | fn test_repeated_packed_fixed_encoding() { 10 | let mut mm = InteropMessageList::new(); 11 | mm.ts.push(InteropMessage { 12 | fixed32_repeated: vec![17, 34], 13 | ..InteropMessage::default() 14 | }); 15 | 16 | let interop_bin = interop_json_decode("{ts: [{fixed32_repeated: [17, 34]}]}"); 17 | let our_bin = mm.write_to_bytes().unwrap(); 18 | // TODO: we are not using packed encoding for fixed 19 | if false { 20 | assert_eq!(encode_hex(&interop_bin), encode_hex(&our_bin)); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /protobuf/src/reflect/oneof/generated.rs: -------------------------------------------------------------------------------- 1 | use crate::OneofFull; 2 | 3 | #[doc(hidden)] 4 | pub struct GeneratedOneofDescriptorData { 5 | pub(crate) name: &'static str, 6 | } 7 | 8 | impl GeneratedOneofDescriptorData { 9 | #[doc(hidden)] 10 | pub fn new(name: &'static str) -> GeneratedOneofDescriptorData 11 | where 12 | O: OneofFull, 13 | { 14 | GeneratedOneofDescriptorData { name } 15 | } 16 | } 17 | 18 | #[derive(Debug)] 19 | pub(crate) struct GeneratedOneofDescriptor {} 20 | 21 | impl GeneratedOneofDescriptor { 22 | /// Synthetic oneof for proto3 optional field. 23 | pub(crate) fn new_synthetic() -> GeneratedOneofDescriptor { 24 | GeneratedOneofDescriptor {} 25 | } 26 | 27 | pub(crate) fn new(_data: &GeneratedOneofDescriptorData) -> GeneratedOneofDescriptor { 28 | GeneratedOneofDescriptor {} 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /test-crates/protobuf-fuzz/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "protobuf-fuzz" 3 | version = "0.0.0" 4 | authors = ["Stepan Koltsov "] 5 | publish = false 6 | edition = "2021" 7 | 8 | [lib] 9 | doctest = false 10 | bench = false 11 | 12 | [features] 13 | default = [] 14 | with-bytes = ["bytes", "protobuf/with-bytes", "protobuf-test-common/with-bytes"] 15 | 16 | [build-dependencies] 17 | protobuf-codegen = { path = "../../protobuf-codegen" } 18 | protobuf-test-common = { path = "../../test-crates/protobuf-test-common" } 19 | glob = "0.2" 20 | log = "0.4" 21 | env_logger = "0.5.*" 22 | 23 | [dependencies] 24 | bytes = { version = "1.1", optional = true } 25 | 26 | protobuf = { path = "../../protobuf" } 27 | protobuf-json-mapping = { path = "../../protobuf-json-mapping" } 28 | protobuf-test-common = { path = "../../test-crates/protobuf-test-common" } 29 | -------------------------------------------------------------------------------- /test-crates/protobuf-test-common/src/bin/varint-encode.rs: -------------------------------------------------------------------------------- 1 | use std::env; 2 | 3 | use protobuf::CodedOutputStream; 4 | use protobuf_test_common::hex::encode_hex; 5 | 6 | fn parse_u64(s: &str) -> anyhow::Result { 7 | if s.starts_with("0x") { 8 | Ok(u64::from_str_radix(&s[2..], 16)?) 9 | } else { 10 | Ok(u64::from_str_radix(s, 10)?) 11 | } 12 | } 13 | 14 | fn main() -> anyhow::Result<()> { 15 | let args: Vec = env::args().skip(1).collect(); 16 | assert_eq!(1, args.len()); 17 | let arg: u64 = parse_u64(&args[0])?; 18 | 19 | let mut varint = Vec::new(); 20 | let mut os = CodedOutputStream::vec(&mut varint); 21 | os.write_raw_varint64(arg)?; 22 | os.flush()?; 23 | drop(os); 24 | 25 | println!("dec: {}", arg); 26 | println!("hex: 0x{:x}", arg); 27 | println!("varint hex: {}", encode_hex(&varint)); 28 | Ok(()) 29 | } 30 | -------------------------------------------------------------------------------- /test-crates/protobuf-codegen-protoc-test/src/common/v2/test_service_pb.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto2"; 2 | 3 | import "google/protobuf/descriptor.proto"; 4 | 5 | import "test_basic_pb.proto"; 6 | 7 | package service; 8 | 9 | extend google.protobuf.MethodOptions { 10 | optional FancyMethodOptions fancy = 50000; 11 | } 12 | 13 | message FancyMethodOptions { 14 | optional bool dotted = 1; 15 | } 16 | 17 | service Service { 18 | rpc ShortForm(Request) returns(Response); 19 | rpc LongForm(Request) returns(Response) { 20 | option (service.fancy).dotted = true; 21 | } 22 | // Dots in request and response types. 23 | rpc DottyShortForm(basic.Test1) returns(basic.Test2); 24 | rpc DottyLongForm(basic.Test1) returns(basic.Test2) { 25 | // Alternate form of above. 26 | option (fancy).dotted = true; 27 | } 28 | } 29 | 30 | message Request { 31 | } 32 | 33 | message Response { 34 | } 35 | -------------------------------------------------------------------------------- /protobuf/src/reflect/rt/v2.rs: -------------------------------------------------------------------------------- 1 | //! This module contains functions references for reflection in generated code. 2 | 3 | #![doc(hidden)] 4 | 5 | pub use crate::reflect::acc::v2::map::make_map_simpler_accessor; 6 | pub use crate::reflect::acc::v2::map::make_map_simpler_accessor_new; 7 | pub use crate::reflect::acc::v2::repeated::make_vec_simpler_accessor; 8 | pub use crate::reflect::acc::v2::singular::make_message_field_accessor; 9 | pub use crate::reflect::acc::v2::singular::make_option_accessor; 10 | pub use crate::reflect::acc::v2::singular::make_simpler_field_accessor; 11 | pub use crate::reflect::acc::v2::singular::oneof::make_oneof_copy_has_get_set_simpler_accessors; 12 | pub use crate::reflect::acc::v2::singular::oneof::make_oneof_deref_has_get_set_simpler_accessor; 13 | pub use crate::reflect::acc::v2::singular::oneof::make_oneof_enum_accessors; 14 | pub use crate::reflect::acc::v2::singular::oneof::make_oneof_message_has_get_mut_set_accessor; 15 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [workspace] 2 | resolver = "2" 3 | members = [ 4 | "ci-gen", 5 | "protoc-bin", 6 | "protobuf", 7 | "protobuf-json-mapping", 8 | "protobuf-codegen", 9 | "protobuf-examples/customize-serde", 10 | "protobuf-examples/dynamic", 11 | "protobuf-examples/pure-vs-protoc", 12 | "protobuf-examples/vs-prost", 13 | "protobuf-examples/issue-614", 14 | "protobuf-parse", 15 | "protobuf-support", 16 | "test-crates/perftest/bytes", 17 | "test-crates/perftest/misc", 18 | "test-crates/perftest/vs-cxx", 19 | "test-crates/protobuf-codegen-identical-test", 20 | "test-crates/protobuf-codegen-protoc-test", 21 | "test-crates/protobuf-codegen-pure-test", 22 | "test-crates/protobuf-parse-error-test", 23 | "test-crates/protobuf-fuzz", 24 | "test-crates/protobuf-test", 25 | "test-crates/protobuf-test-common", 26 | ] 27 | 28 | [workspace.dependencies] 29 | protoc-bin-vendored = "=3.1.0" 30 | -------------------------------------------------------------------------------- /protobuf/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | 3 | name = "protobuf" 4 | version = "4.0.0-alpha.0" 5 | authors = ["Stepan Koltsov "] 6 | edition = "2021" 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 | default = [] 21 | 22 | [dependencies] 23 | bytes = { version = "1.1", optional = true } 24 | thiserror = "1.0.30" 25 | once_cell = "1.9.0" 26 | 27 | protobuf-support = { path = "../protobuf-support", version = "=4.0.0-alpha.0" } 28 | 29 | [package.metadata.docs.rs] 30 | all-features = true 31 | 32 | [lints.rust] 33 | unexpected_cfgs = { level = "warn", check-cfg = ['cfg(never)'] } 34 | -------------------------------------------------------------------------------- /protobuf/src/reflect/repeated/drain_iter.rs: -------------------------------------------------------------------------------- 1 | use crate::reflect::runtime_types::RuntimeTypeTrait; 2 | use crate::reflect::ProtobufValue; 3 | use crate::reflect::ReflectValueBox; 4 | 5 | pub(crate) struct ReflectRepeatedDrainIter<'a> { 6 | imp: Box + 'a>, 7 | } 8 | 9 | impl<'a> ReflectRepeatedDrainIter<'a> { 10 | pub(crate) fn new( 11 | imp: impl Iterator + 'a, 12 | ) -> ReflectRepeatedDrainIter<'a> { 13 | ReflectRepeatedDrainIter { imp: Box::new(imp) } 14 | } 15 | 16 | pub(crate) fn new_vec(v: &'a mut Vec) -> ReflectRepeatedDrainIter<'a> { 17 | ReflectRepeatedDrainIter::new(v.drain(..).map(V::RuntimeType::into_value_box)) 18 | } 19 | } 20 | 21 | impl<'a> Iterator for ReflectRepeatedDrainIter<'a> { 22 | type Item = ReflectValueBox; 23 | 24 | fn next(&mut self) -> Option { 25 | self.imp.next() 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /test-crates/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 = "2021" 7 | description = "Test pure codegen" 8 | 9 | [lib] 10 | doctest = false 11 | bench = false 12 | 13 | [features] 14 | default = [] 15 | proto3 = [] 16 | with-bytes = ["bytes", "protobuf/with-bytes", "protobuf-test-common/with-bytes"] 17 | 18 | [build-dependencies] 19 | protobuf-codegen = { path = "../../protobuf-codegen" } 20 | protobuf-test-common = { path = "../../test-crates/protobuf-test-common" } 21 | glob = "0.2" 22 | log = "0.4" 23 | env_logger = "0.5.*" 24 | 25 | [dependencies] 26 | bytes = { version = "1.1", optional = true } 27 | 28 | protobuf = { path = "../../protobuf" } 29 | protobuf-test-common = { path = "../../test-crates/protobuf-test-common" } 30 | protobuf-json-mapping = { path = "../../protobuf-json-mapping" } 31 | -------------------------------------------------------------------------------- /protobuf/src/reflect/repeated/iter.rs: -------------------------------------------------------------------------------- 1 | use crate::reflect::runtime_types::RuntimeTypeTrait; 2 | use crate::reflect::ProtobufValue; 3 | use crate::reflect::ReflectValueRef; 4 | 5 | pub(crate) struct ReflectRepeatedIter<'a> { 6 | imp: Box> + 'a>, 7 | } 8 | 9 | impl<'a> ReflectRepeatedIter<'a> { 10 | pub(crate) fn new( 11 | iter: impl Iterator> + 'a, 12 | ) -> ReflectRepeatedIter<'a> { 13 | ReflectRepeatedIter { 14 | imp: Box::new(iter), 15 | } 16 | } 17 | 18 | pub(crate) fn new_slice(slice: &'a [V]) -> ReflectRepeatedIter<'a> { 19 | ReflectRepeatedIter::new(slice.into_iter().map(V::RuntimeType::as_ref)) 20 | } 21 | } 22 | 23 | impl<'a> Iterator for ReflectRepeatedIter<'a> { 24 | type Item = ReflectValueRef<'a>; 25 | 26 | fn next(&mut self) -> Option> { 27 | self.imp.next() 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /protobuf/src/rt/message.rs: -------------------------------------------------------------------------------- 1 | use crate::wire_format::WireType; 2 | use crate::CodedInputStream; 3 | use crate::CodedOutputStream; 4 | use crate::Message; 5 | use crate::MessageField; 6 | 7 | /// Read singular `message` field. 8 | pub fn read_singular_message_into_field( 9 | is: &mut CodedInputStream, 10 | target: &mut MessageField, 11 | ) -> crate::Result<()> 12 | where 13 | M: Message, 14 | { 15 | let mut m = M::new(); 16 | is.merge_message(&mut m)?; 17 | *target = MessageField::some(m); 18 | Ok(()) 19 | } 20 | 21 | /// Write message with field number and length to the stream. 22 | pub fn write_message_field_with_cached_size( 23 | field_number: u32, 24 | message: &M, 25 | os: &mut CodedOutputStream, 26 | ) -> crate::Result<()> 27 | where 28 | M: Message, 29 | { 30 | os.write_tag(field_number, WireType::LengthDelimited)?; 31 | os.write_raw_varint32(message.cached_size())?; 32 | message.write_to_with_cached_sizes(os) 33 | } 34 | -------------------------------------------------------------------------------- /google-protobuf-all-protos/protobuf/protobuf-git/php/tests/proto/test_wrapper_type_setters.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | import "google/protobuf/wrappers.proto"; 4 | 5 | package foo; 6 | 7 | message TestWrapperSetters { 8 | google.protobuf.DoubleValue double_value = 1; 9 | google.protobuf.FloatValue float_value = 2; 10 | google.protobuf.Int64Value int64_value = 3; 11 | google.protobuf.UInt64Value uint64_value = 4; 12 | google.protobuf.Int32Value int32_value = 5; 13 | google.protobuf.UInt32Value uint32_value = 6; 14 | google.protobuf.BoolValue bool_value = 7; 15 | google.protobuf.StringValue string_value = 8; 16 | google.protobuf.BytesValue bytes_value = 9; 17 | 18 | oneof wrapped_oneofs { 19 | google.protobuf.DoubleValue double_value_oneof = 10; 20 | google.protobuf.StringValue string_value_oneof = 11; 21 | } 22 | 23 | repeated google.protobuf.StringValue repeated_string_value = 12; 24 | 25 | map map_string_value = 13; 26 | } 27 | -------------------------------------------------------------------------------- /protobuf-codegen/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "protobuf-codegen" 3 | version = "4.0.0-alpha.0" 4 | authors = ["Stepan Koltsov "] 5 | edition = "2021" 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 to invoke programmatically (e. g. from `build.rs`) and `protoc-gen-rs` binary. 13 | """ 14 | 15 | [lib] 16 | bench = false 17 | 18 | [dependencies] 19 | thiserror = "1.0.30" 20 | anyhow = "1.0.53" 21 | regex = "1.5.5" 22 | once_cell = "1.10.0" 23 | tempfile = "3" 24 | 25 | protobuf = { path = "../protobuf", version = "=4.0.0-alpha.0" } 26 | protobuf-parse = { path = "../protobuf-parse", version = "=4.0.0-alpha.0" } 27 | 28 | [[bin]] 29 | 30 | name = "protoc-gen-rs" 31 | path = "src/bin/protoc-gen-rs.rs" 32 | test = false 33 | 34 | [package.metadata.docs.rs] 35 | all-features = true 36 | -------------------------------------------------------------------------------- /protobuf-parse/src/bin/parse-and-typecheck.rs: -------------------------------------------------------------------------------- 1 | use std::env; 2 | use std::path::PathBuf; 3 | use std::process::exit; 4 | 5 | use protobuf_parse::Parser; 6 | 7 | fn main() { 8 | let args = env::args_os() 9 | .skip(1) 10 | .map(PathBuf::from) 11 | .collect::>(); 12 | 13 | if args.len() != 2 { 14 | eprintln!( 15 | "usage: {} ", 16 | env::args().next().unwrap() 17 | ); 18 | exit(1); 19 | } 20 | 21 | eprintln!( 22 | "{} is not a part of public interface", 23 | env::args().next().unwrap() 24 | ); 25 | 26 | assert!(args.len() >= 2); 27 | let (input, includes) = args.split_at(1); 28 | let t = Parser::new() 29 | .pure() 30 | .includes(includes) 31 | .inputs(input) 32 | .parse_and_typecheck() 33 | .expect("parse_and_typecheck"); 34 | for fd in t.file_descriptors { 35 | println!("{:#?}", fd); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /protobuf/src/reflect/field/protobuf_field_type.rs: -------------------------------------------------------------------------------- 1 | use crate::reflect::protobuf_type_box::ProtobufType; 2 | use crate::reflect::RuntimeFieldType; 3 | 4 | /// Reflective representation of field type plus wire type. 5 | pub(crate) enum ProtobufFieldType { 6 | /// Singular field (required, optional for proto2 or singular for proto3) 7 | Singular(ProtobufType), 8 | /// Repeated field 9 | Repeated(ProtobufType), 10 | /// Map field 11 | Map(ProtobufType, ProtobufType), 12 | } 13 | 14 | impl ProtobufFieldType { 15 | /// Drop wire type from the type. 16 | pub fn runtime(&self) -> RuntimeFieldType { 17 | match self { 18 | ProtobufFieldType::Singular(t) => RuntimeFieldType::Singular(t.runtime().clone()), 19 | ProtobufFieldType::Repeated(t) => RuntimeFieldType::Repeated(t.runtime().clone()), 20 | ProtobufFieldType::Map(kt, vt) => { 21 | RuntimeFieldType::Map(kt.runtime().clone(), vt.runtime().clone()) 22 | } 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /protobuf/src/varint/generic.rs: -------------------------------------------------------------------------------- 1 | use crate::rt::compute_raw_varint64_size; 2 | 3 | /// Helper trait implemented by integer types which could be encoded as varint. 4 | pub(crate) trait ProtobufVarint { 5 | /// Size of self when encoded as varint. 6 | fn len_varint(&self) -> u64; 7 | } 8 | 9 | impl ProtobufVarint for u64 { 10 | fn len_varint(&self) -> u64 { 11 | compute_raw_varint64_size(*self) 12 | } 13 | } 14 | 15 | impl ProtobufVarint for u32 { 16 | fn len_varint(&self) -> u64 { 17 | (*self as u64).len_varint() 18 | } 19 | } 20 | 21 | impl ProtobufVarint for i64 { 22 | fn len_varint(&self) -> u64 { 23 | // same as length of u64 24 | (*self as u64).len_varint() 25 | } 26 | } 27 | 28 | impl ProtobufVarint for i32 { 29 | fn len_varint(&self) -> u64 { 30 | // sign-extend and then compute 31 | (*self as i64).len_varint() 32 | } 33 | } 34 | 35 | impl ProtobufVarint for bool { 36 | fn len_varint(&self) -> u64 { 37 | 1 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /test-crates/protobuf-codegen-protoc-test/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "protobuf-codegen-protoc-test" 3 | version = "0.0.0" 4 | authors = ["Stepan Koltsov "] 5 | publish = false 6 | edition = "2021" 7 | description = "Test protoc codegen" 8 | 9 | [lib] 10 | doctest = false 11 | bench = false 12 | 13 | [features] 14 | default = [] 15 | proto3 = [] 16 | with-bytes = ["bytes", "protobuf/with-bytes", "protobuf-test-common/with-bytes"] 17 | 18 | [build-dependencies] 19 | glob = "0.2" 20 | log = "0.4" 21 | env_logger = "0.5.*" 22 | 23 | protoc-bin-vendored = { workspace = true } 24 | 25 | protobuf-codegen = { path = "../../protobuf-codegen" } 26 | protobuf-test-common = { path = "../../test-crates/protobuf-test-common" } 27 | 28 | [dependencies] 29 | bytes = { version = "1.1", optional = true } 30 | 31 | protobuf = { path = "../../protobuf" } 32 | protobuf-test-common = { path = "../../test-crates/protobuf-test-common" } 33 | protobuf-json-mapping = { path = "../../protobuf-json-mapping" } 34 | -------------------------------------------------------------------------------- /test-crates/protobuf-codegen-protoc-test/src/common/v2/test_enum_alias.rs: -------------------------------------------------------------------------------- 1 | use protobuf::Enum; 2 | use protobuf::EnumFull; 3 | use protobuf_test_common::*; 4 | 5 | use super::test_enum_alias_pb::*; 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_with_dynamic("08 0a", &m); 28 | } 29 | 30 | #[test] 31 | fn descriptor() { 32 | assert_eq!("A", EnumWithAlias::A.descriptor().name()); 33 | assert_eq!("A_AGAIN", EnumWithAlias::A_AGAIN.descriptor().name()); 34 | } 35 | -------------------------------------------------------------------------------- /protobuf-examples/pure-vs-protoc/build.rs: -------------------------------------------------------------------------------- 1 | use protobuf_codegen::Codegen; 2 | 3 | fn main() { 4 | // We generate descriptors twice: with pure rust codegen 5 | // and with codegen depending on `protoc` binary. 6 | // This is for demonstration purposes; in practice you'd need either of them. 7 | // 8 | // Note there's a third option: using `protoc` binary directly and `protoc-gen-rs` 9 | // plugin, this is a canonical way to generate protobuf sources. 10 | // This is not possible to do with Cargo (since Cargo cannot depend on binaries) 11 | // but can be used with some other build system. 12 | 13 | Codegen::new() 14 | .protoc() 15 | .cargo_out_dir("generated_with_native") 16 | .input("src/protos/example.proto") 17 | .include("src/protos") 18 | .run_from_script(); 19 | 20 | Codegen::new() 21 | .pure() 22 | .cargo_out_dir("generated_with_pure") 23 | .input("src/protos/example.proto") 24 | .include("src/protos") 25 | .run_from_script(); 26 | } 27 | -------------------------------------------------------------------------------- /protobuf/src/reflect/reflect_eq.rs: -------------------------------------------------------------------------------- 1 | /// Parameter for [`ReflectEq`]. 2 | #[derive(Debug, Default)] 3 | pub struct ReflectEqMode { 4 | /// When `true`, `NaN` values are considered equal to each other. 5 | pub nan_equal: bool, 6 | _non_exhausitve: (), 7 | } 8 | 9 | impl ReflectEqMode { 10 | /// Default equality, similar to `#[derive(PartialEq)]`. 11 | pub fn default() -> ReflectEqMode { 12 | Default::default() 13 | } 14 | 15 | /// Equality where float `NaN` values are considered equal to each other. 16 | /// 17 | /// Useful in tests. 18 | pub fn nan_equal() -> ReflectEqMode { 19 | ReflectEqMode { 20 | nan_equal: true, 21 | ..Default::default() 22 | } 23 | } 24 | } 25 | 26 | /// Special version of eq. 27 | /// 28 | /// With `mode` [`ReflectEqMode::default()`], should be equivalent 29 | /// to `#[derive(PartialEq)]`. 30 | pub trait ReflectEq { 31 | /// Perform the equality comparison. 32 | fn reflect_eq(&self, that: &Self, mode: &ReflectEqMode) -> bool; 33 | } 34 | -------------------------------------------------------------------------------- /protobuf/src/coded_output_stream/with.rs: -------------------------------------------------------------------------------- 1 | use std::io::Write; 2 | 3 | use crate::CodedOutputStream; 4 | 5 | pub(crate) trait WithCodedOutputStream { 6 | fn with_coded_output_stream(self, cb: F) -> crate::Result 7 | where 8 | F: FnOnce(&mut CodedOutputStream) -> crate::Result; 9 | } 10 | 11 | impl<'a> WithCodedOutputStream for &'a mut (dyn Write + 'a) { 12 | fn with_coded_output_stream(self, cb: F) -> crate::Result 13 | where 14 | F: FnOnce(&mut CodedOutputStream) -> crate::Result, 15 | { 16 | let mut os = CodedOutputStream::new(self); 17 | let r = cb(&mut os)?; 18 | os.flush()?; 19 | Ok(r) 20 | } 21 | } 22 | 23 | impl<'a> WithCodedOutputStream for &'a mut Vec { 24 | fn with_coded_output_stream(mut self, cb: F) -> crate::Result 25 | where 26 | F: FnOnce(&mut CodedOutputStream) -> crate::Result, 27 | { 28 | let mut os = CodedOutputStream::vec(&mut self); 29 | let r = cb(&mut os)?; 30 | os.flush()?; 31 | Ok(r) 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /protobuf/src/enums.rs: -------------------------------------------------------------------------------- 1 | use std::fmt; 2 | 3 | /// Trait implemented by all protobuf enum types. 4 | /// 5 | /// Additionally, generated enums also implement [`EnumFull`](crate::EnumFull) trait, 6 | /// which provides access to reflection. 7 | pub trait Enum: Eq + Sized + Copy + fmt::Debug + Default + Send + Sync + 'static { 8 | /// Enum name as specified in `.proto` file. 9 | /// 10 | /// There's full reflection when non-lite runtime code generation is used, 11 | /// and enums implement [`EnumFull`](crate::EnumFull) trait. 12 | /// This operation is for lite runtime. 13 | const NAME: &'static str; 14 | 15 | /// Get enum `i32` value. 16 | fn value(&self) -> i32; 17 | 18 | /// Try to create an enum from `i32` value. 19 | /// Return `None` if value is unknown. 20 | fn from_i32(v: i32) -> Option; 21 | 22 | /// Try to create an enum from `&str` value. 23 | /// Return `None` if str is unknown. 24 | fn from_str(s: &str) -> Option; 25 | 26 | /// All enum values for enum type. 27 | const VALUES: &'static [Self] = &[]; 28 | } 29 | -------------------------------------------------------------------------------- /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 | //! # JSON 23 | //! 24 | //! rust-protobuf also supports JSON printing and parsing. 25 | //! It is implemented in 26 | //! [`protobuf-json-mapping` crate](https://docs.rs/protobuf-json-mapping/%3E=3.0.0-alpha). 27 | 28 | mod parse; 29 | mod print; 30 | 31 | pub use self::parse::merge_from_str; 32 | pub use self::parse::parse_from_str; 33 | pub use self::parse::ParseError; 34 | pub use self::print::fmt; 35 | pub use self::print::print_to; 36 | pub use self::print::print_to_string; 37 | pub use self::print::print_to_string_pretty; 38 | -------------------------------------------------------------------------------- /test-crates/protobuf-codegen-protoc-test/src/common/v2/test_oneof_basic_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/src/special.rs: -------------------------------------------------------------------------------- 1 | use crate::cached_size::CachedSize; 2 | use crate::UnknownFields; 3 | 4 | /// Special fields included in each generated message. 5 | #[derive(Default, Eq, PartialEq, Clone, Debug, Hash)] 6 | pub struct SpecialFields { 7 | unknown_fields: UnknownFields, 8 | cached_size: CachedSize, 9 | } 10 | 11 | impl SpecialFields { 12 | /// Defaults. 13 | pub const fn new() -> SpecialFields { 14 | SpecialFields { 15 | unknown_fields: UnknownFields::new(), 16 | cached_size: CachedSize::new(), 17 | } 18 | } 19 | 20 | /// Clear. 21 | pub fn clear(&mut self) { 22 | self.unknown_fields.clear(); 23 | // No need to clear `cached_size`. 24 | } 25 | 26 | /// Getter. 27 | pub fn cached_size(&self) -> &CachedSize { 28 | &self.cached_size 29 | } 30 | 31 | /// Getter. 32 | pub fn unknown_fields(&self) -> &UnknownFields { 33 | &self.unknown_fields 34 | } 35 | 36 | /// Setter. 37 | pub fn mut_unknown_fields(&mut self) -> &mut UnknownFields { 38 | &mut self.unknown_fields 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /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. 20 | -------------------------------------------------------------------------------- /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. 20 | -------------------------------------------------------------------------------- /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. 20 | -------------------------------------------------------------------------------- /protobuf-support/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. 20 | -------------------------------------------------------------------------------- /protobuf-json-mapping/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. 20 | -------------------------------------------------------------------------------- /test-crates/protobuf-codegen-protoc-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-codegen-protoc-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-codegen/src/gen/rust/component.rs: -------------------------------------------------------------------------------- 1 | use std::fmt; 2 | use std::fmt::Formatter; 3 | 4 | use crate::gen::rust::ident::RustIdent; 5 | use crate::gen::rust::keywords::parse_rust_keyword; 6 | 7 | #[derive(Clone, Debug, PartialEq, Eq, Hash)] 8 | pub(crate) enum RustPathComponent { 9 | Ident(RustIdent), 10 | Keyword(&'static str), 11 | } 12 | 13 | impl fmt::Display for RustPathComponent { 14 | fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { 15 | match self { 16 | RustPathComponent::Ident(ident) => write!(f, "{}", ident), 17 | RustPathComponent::Keyword(keyword) => write!(f, "{}", keyword), 18 | } 19 | } 20 | } 21 | 22 | impl RustPathComponent { 23 | pub(crate) const SUPER: RustPathComponent = RustPathComponent::Keyword("super"); 24 | 25 | pub(crate) fn parse(s: &str) -> RustPathComponent { 26 | if s.starts_with("r#") { 27 | RustPathComponent::Ident(RustIdent::new(&s[2..])) 28 | } else if let Some(kw) = parse_rust_keyword(s) { 29 | RustPathComponent::Keyword(kw) 30 | } else { 31 | RustPathComponent::Ident(RustIdent::new(s)) 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /test-crates/protobuf-codegen-protoc-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.int32_field() 29 | }) 30 | }) 31 | .collect(); 32 | 33 | let results = threads 34 | .into_iter() 35 | .map(|t| t.join().unwrap()) 36 | .collect::>(); 37 | assert_eq!(&[23, 23, 23, 23], &results[..]); 38 | } 39 | -------------------------------------------------------------------------------- /protobuf/src/reflect/type_dynamic.rs: -------------------------------------------------------------------------------- 1 | //! Reflection internals. 2 | 3 | use std::marker; 4 | 5 | use crate::reflect::runtime_types::RuntimeTypeTrait; 6 | use crate::reflect::types::ProtobufTypeTrait; 7 | use crate::reflect::ProtobufValue; 8 | use crate::reflect::RuntimeType; 9 | use crate::wire_format::WireType; 10 | 11 | /// Dynamic version of [`ProtobufType`](crate::reflect::types::ProtobufType). 12 | /// 13 | /// This is used internally. 14 | pub(crate) trait _ProtobufTypeDynamic: Send + Sync + 'static { 15 | /// Wire type for this type. 16 | fn wire_type(&self) -> WireType; 17 | 18 | /// Get runtime type for this protobuf type. 19 | fn runtime_type(&self) -> RuntimeType; 20 | } 21 | 22 | pub(crate) struct _ProtobufTypeDynamicImpl(pub marker::PhantomData); 23 | 24 | impl _ProtobufTypeDynamic for _ProtobufTypeDynamicImpl 25 | where 26 | T: ProtobufTypeTrait, 27 | ::ProtobufValue: ProtobufValue, 28 | { 29 | fn wire_type(&self) -> WireType { 30 | T::WIRE_TYPE 31 | } 32 | 33 | fn runtime_type(&self) -> RuntimeType { 34 | ::RuntimeType::runtime_type_box() 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /protobuf-parse/src/test_against_protobuf_protos.rs: -------------------------------------------------------------------------------- 1 | #![cfg(test)] 2 | 3 | use std::fs; 4 | use std::io::Read; 5 | use std::path::Path; 6 | 7 | use anyhow::Context; 8 | 9 | use crate::model; 10 | 11 | fn parse_recursively(path: &Path) { 12 | assert!(path.exists()); 13 | 14 | let file_name = path 15 | .file_name() 16 | .expect("file_name") 17 | .to_str() 18 | .expect("to_str"); 19 | if path.is_dir() { 20 | for entry in fs::read_dir(path).expect("read_dir") { 21 | parse_recursively(&entry.expect("entry").path()); 22 | } 23 | } else if file_name.ends_with(".proto") { 24 | println!("checking {}", path.display()); 25 | let mut content = String::new(); 26 | fs::File::open(path) 27 | .expect("open") 28 | .read_to_string(&mut content) 29 | .expect("read"); 30 | model::FileDescriptor::parse(&content) 31 | .with_context(|| format!("testing `{}`", path.display())) 32 | .expect("parse"); 33 | } 34 | } 35 | 36 | #[test] 37 | fn test() { 38 | let path = &Path::new("../google-protobuf-all-protos/protobuf"); 39 | parse_recursively(&Path::new(path)); 40 | } 41 | -------------------------------------------------------------------------------- /protobuf/src/reflect/error.rs: -------------------------------------------------------------------------------- 1 | #[derive(Debug, thiserror::Error)] 2 | pub(crate) enum ReflectError { 3 | #[error("Message `{}` not found in files: {}", .0, .1)] 4 | MessageNotFoundInFiles(String, String), 5 | #[error("Dependency `{}` of `{}` not found; all deps: {}", .0, .1, .2)] 6 | DependencyNotFound(String, String, String), 7 | #[error("Non-unique dependencies given: {}", .0)] 8 | NonUniqueDependencies(String), 9 | #[error("Non-unique field name: `{0}`")] 10 | NonUniqueFieldName(String), 11 | #[error("Non-unique file descriptor: `{0}`")] 12 | NonUniqueFileDescriptor(String), 13 | #[error("Cycle in provided file descriptors")] 14 | CycleInFileDescriptors, 15 | #[error("Map entry message name must end with `Entry`")] 16 | MapEntryNameMustEndWithEntry, 17 | #[error("Map entry message must have no extensions, nested messages or enums")] 18 | MapEntryMustHaveNo, 19 | #[error( 20 | "Map entry message must have two optional fields, \ 21 | numbered 1 and 2 and named `key` and `value`" 22 | )] 23 | MapEntryIncorrectFields, 24 | #[error("Could not parse default value for field {0}")] 25 | CouldNotParseDefaultValueForField(String), 26 | } 27 | -------------------------------------------------------------------------------- /test-crates/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 = "2021" 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 | -------------------------------------------------------------------------------- /test-crates/perftest/misc/build.rs: -------------------------------------------------------------------------------- 1 | use std::env; 2 | use std::io::Read; 3 | use std::process; 4 | 5 | // % rustc +stable --version 6 | // rustc 1.26.0 (a77568041 2018-05-07) 7 | // % rustc +beta --version 8 | // rustc 1.27.0-beta.1 (03fb2f447 2018-05-09) 9 | // % rustc +nightly --version 10 | // rustc 1.27.0-nightly (acd3871ba 2018-05-10) 11 | fn version_is_nightly(version: &str) -> bool { 12 | version.contains("nightly") 13 | } 14 | 15 | fn export_rustc_cfg() { 16 | let rustc = env::var("RUSTC").expect("RUSTC unset"); 17 | 18 | let mut child = process::Command::new(rustc) 19 | .args(&["--version"]) 20 | .stdin(process::Stdio::null()) 21 | .stdout(process::Stdio::piped()) 22 | .spawn() 23 | .expect("spawn rustc"); 24 | 25 | let mut rustc_version = String::new(); 26 | 27 | child 28 | .stdout 29 | .as_mut() 30 | .expect("stdout") 31 | .read_to_string(&mut rustc_version) 32 | .expect("read_to_string"); 33 | assert!(child.wait().expect("wait").success()); 34 | 35 | if version_is_nightly(&rustc_version) { 36 | println!("cargo:rustc-cfg=rustc_nightly"); 37 | } 38 | } 39 | 40 | fn main() { 41 | export_rustc_cfg(); 42 | } 43 | -------------------------------------------------------------------------------- /protobuf-parse/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "protobuf-parse" 3 | version = "4.0.0-alpha.0" 4 | edition = "2021" 5 | authors = ["Stepan Koltsov "] 6 | license = "MIT" 7 | homepage = "https://github.com/stepancheg/rust-protobuf/tree/master/protobuf-parse/" 8 | repository = "https://github.com/stepancheg/rust-protobuf/tree/master/protobuf-parse/" 9 | description = """ 10 | Parse `.proto` files. 11 | 12 | Files are parsed into a `protobuf::descriptor::FileDescriptorSet` object using either: 13 | * pure rust parser (no dependencies) 14 | * `protoc` binary (more reliable and compatible with Google's implementation) 15 | """ 16 | 17 | [dependencies] 18 | tempfile = "3.2.0" 19 | log = "0.4" 20 | which = "4.0" 21 | anyhow = "1.0.53" 22 | thiserror = "1.0.30" 23 | indexmap = "2.0.0" 24 | 25 | protobuf = { path = "../protobuf", version = "=4.0.0-alpha.0" } 26 | protobuf-support = { path = "../protobuf-support", version = "=4.0.0-alpha.0" } 27 | 28 | [lib] 29 | # TODO: figure out what to do with bundled linked_hash_map 30 | doctest = false 31 | 32 | [[bin]] 33 | 34 | name = "parse-and-typecheck" 35 | path = "src/bin/parse-and-typecheck.rs" 36 | test = false 37 | 38 | [package.metadata.docs.rs] 39 | all-features = true 40 | -------------------------------------------------------------------------------- /test-crates/protobuf-codegen-protoc-test/src/common/v2/test_map_tokio.rs: -------------------------------------------------------------------------------- 1 | use bytes::Bytes; 2 | use protobuf::*; 3 | use protobuf_test_common::*; 4 | 5 | use super::test_map_tokio_pb::*; 6 | 7 | #[test] 8 | fn test_string_to_int32() { 9 | let mut map = TestMapTokio::new(); 10 | map.string_to_int32.insert(Chars::from("abc"), 17); 11 | test_serialize_deserialize_with_dynamic("0a 07 0a 03 61 62 63 10 11", &map); 12 | // field 1, length-delimited 13 | // length 14 | // field 1, wire type 2 15 | // length 16 | // a b c 17 | // field 2, varint 18 | // 17 19 | } 20 | 21 | #[test] 22 | fn test_int32_to_bytes() { 23 | let mut map = TestMapTokio::new(); 24 | map.int32_to_string.insert(17, Chars::from("abc")); 25 | test_serialize_deserialize_with_dynamic("12 07 08 11 12 03 61 62 63", &map); 26 | let mut map = TestMapTokio::new(); 27 | map.int32_to_bytes.insert(17, Bytes::from("abc")); 28 | test_serialize_deserialize_with_dynamic("1a 07 08 11 12 03 61 62 63", &map); 29 | } 30 | -------------------------------------------------------------------------------- /protobuf-parse/src/proto/mod.rs: -------------------------------------------------------------------------------- 1 | //! This folder contains copy of .proto files 2 | //! needed for pure codegen. 3 | //! 4 | //! Files are copied here because when publishing to crates, 5 | //! referencing files from outside is not allowed. 6 | 7 | pub(crate) const RUSTPROTO_PROTO: &str = include_str!("rustproto.proto"); 8 | pub(crate) const ANY_PROTO: &str = include_str!("google/protobuf/any.proto"); 9 | pub(crate) const API_PROTO: &str = include_str!("google/protobuf/api.proto"); 10 | pub(crate) const DESCRIPTOR_PROTO: &str = include_str!("google/protobuf/descriptor.proto"); 11 | pub(crate) const DURATION_PROTO: &str = include_str!("google/protobuf/duration.proto"); 12 | pub(crate) const EMPTY_PROTO: &str = include_str!("google/protobuf/empty.proto"); 13 | pub(crate) const FIELD_MASK_PROTO: &str = include_str!("google/protobuf/field_mask.proto"); 14 | pub(crate) const SOURCE_CONTEXT_PROTO: &str = include_str!("google/protobuf/source_context.proto"); 15 | pub(crate) const STRUCT_PROTO: &str = include_str!("google/protobuf/struct.proto"); 16 | pub(crate) const TIMESTAMP_PROTO: &str = include_str!("google/protobuf/timestamp.proto"); 17 | pub(crate) const TYPE_PROTO: &str = include_str!("google/protobuf/type.proto"); 18 | pub(crate) const WRAPPERS_PROTO: &str = include_str!("google/protobuf/wrappers.proto"); 19 | -------------------------------------------------------------------------------- /protobuf-parse/examples/file-descriptor-out-compare.rs: -------------------------------------------------------------------------------- 1 | use std::env; 2 | use std::fs; 3 | 4 | use protobuf::text_format; 5 | use protobuf_parse::Parser; 6 | 7 | enum Which { 8 | Protoc, 9 | Pure, 10 | } 11 | 12 | fn main() { 13 | let args = env::args().skip(1).collect::>(); 14 | let args = args.iter().map(|s| s.as_str()).collect::>(); 15 | let (path, out_protoc, out_pure) = match args.as_slice() { 16 | // Just invoke protoc. 17 | [path, out_protoc, out_pure] => (path, out_protoc, out_pure), 18 | _ => panic!("wrong args"), 19 | }; 20 | 21 | for which in [Which::Pure, Which::Protoc] { 22 | let mut parser = Parser::new(); 23 | match which { 24 | Which::Protoc => { 25 | parser.protoc(); 26 | } 27 | Which::Pure => { 28 | parser.pure(); 29 | } 30 | } 31 | 32 | parser.input(path); 33 | parser.include("."); 34 | let fds = parser.file_descriptor_set().unwrap(); 35 | let fds = text_format::print_to_string_pretty(&fds); 36 | let out = match which { 37 | Which::Protoc => out_protoc, 38 | Which::Pure => out_pure, 39 | }; 40 | fs::write(out, fds).unwrap(); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /test-crates/protobuf-codegen-protoc-test/src/common/v2/test_any.rs: -------------------------------------------------------------------------------- 1 | use protobuf::well_known_types::any::Any; 2 | use protobuf::MessageFull; 3 | 4 | use super::test_any_pb::MessageOne; 5 | use super::test_any_pb::MessageTwo; 6 | 7 | #[test] 8 | fn test_static() { 9 | let mut m1 = MessageOne::new(); 10 | m1.set_i(10); 11 | let any = Any::pack(&m1).unwrap(); 12 | assert_eq!("type.googleapis.com/test_any.MessageOne", any.type_url); 13 | assert!(any.is::()); 14 | assert!(!any.is::()); 15 | assert_eq!(Some(m1), any.unpack::().unwrap()); 16 | assert_eq!(None, any.unpack::().unwrap()); 17 | } 18 | 19 | #[test] 20 | fn test_dynamic() { 21 | let mut m1 = MessageOne::new(); 22 | m1.set_i(10); 23 | let any = Any::pack_dyn(&m1).unwrap(); 24 | assert_eq!("type.googleapis.com/test_any.MessageOne", any.type_url); 25 | assert!(any.is_dyn(&MessageOne::descriptor())); 26 | assert!(!any.is_dyn(&MessageTwo::descriptor())); 27 | assert_eq!( 28 | m1, 29 | *any.unpack_dyn(&MessageOne::descriptor()) 30 | .unwrap() 31 | .unwrap() 32 | .downcast_box::() 33 | .unwrap() 34 | ); 35 | assert!(any.unpack_dyn(&MessageTwo::descriptor()).unwrap().is_none()); 36 | } 37 | -------------------------------------------------------------------------------- /protobuf/src/rt/map.rs: -------------------------------------------------------------------------------- 1 | use crate::error::WireError; 2 | use crate::wire_format::WireType; 3 | use crate::CodedInputStream; 4 | 5 | pub(crate) fn read_map_template_new( 6 | is: &mut CodedInputStream, 7 | mut key: impl FnMut(WireType, &mut CodedInputStream) -> crate::Result<()>, 8 | mut value: impl FnMut(WireType, &mut CodedInputStream) -> crate::Result<()>, 9 | ) -> crate::Result<()> { 10 | let len = is.read_raw_varint32()?; 11 | let old_limit = is.push_limit(len as u64)?; 12 | while !is.eof()? { 13 | let (field_number, wire_type) = is.read_tag_unpack()?; 14 | match field_number { 15 | 1 => key(wire_type, is)?, 16 | 2 => value(wire_type, is)?, 17 | _ => is.skip_field(wire_type)?, 18 | } 19 | } 20 | is.pop_limit(old_limit); 21 | Ok(()) 22 | } 23 | 24 | pub(crate) fn read_map_template( 25 | wire_type: WireType, 26 | is: &mut CodedInputStream, 27 | key: impl FnMut(WireType, &mut CodedInputStream) -> crate::Result<()>, 28 | value: impl FnMut(WireType, &mut CodedInputStream) -> crate::Result<()>, 29 | ) -> crate::Result<()> { 30 | if wire_type != WireType::LengthDelimited { 31 | return Err(WireError::UnexpectedWireType(wire_type).into()); 32 | } 33 | 34 | read_map_template_new(is, key, value) 35 | } 36 | -------------------------------------------------------------------------------- /test-crates/protobuf-codegen-protoc-test/src/v2/test_is_initialized.rs: -------------------------------------------------------------------------------- 1 | use protobuf::reflect::FileDescriptor; 2 | use protobuf::reflect::ReflectValueBox; 3 | use protobuf::MessageDyn; 4 | 5 | use crate::v2::test_is_initialized_pb; 6 | use crate::v2::test_is_initialized_pb::TestIsInitialized; 7 | 8 | fn file_descriptor_dynamic() -> FileDescriptor { 9 | FileDescriptor::new_dynamic( 10 | test_is_initialized_pb::file_descriptor().proto().clone(), 11 | &[], 12 | ) 13 | .unwrap() 14 | } 15 | 16 | fn test_is_initialized(message: &mut dyn MessageDyn) { 17 | assert!(!message.is_initialized_dyn()); 18 | let field = message.descriptor_dyn().field_by_name("a").unwrap(); 19 | field.set_singular_field(message, ReflectValueBox::I32(10)); 20 | assert!(message.is_initialized_dyn()); 21 | } 22 | 23 | #[test] 24 | fn is_initialized_generated() { 25 | let mut message = TestIsInitialized::new(); 26 | test_is_initialized(&mut message); 27 | } 28 | 29 | #[test] 30 | fn is_initialized_dynamic() { 31 | let file_descriptor = file_descriptor_dynamic(); 32 | let message_descriptor = file_descriptor 33 | .message_by_package_relative_name("TestIsInitialized") 34 | .unwrap(); 35 | let mut message = message_descriptor.new_instance(); 36 | test_is_initialized(&mut *message); 37 | } 38 | -------------------------------------------------------------------------------- /protobuf/src/coded_output_stream/output_target.rs: -------------------------------------------------------------------------------- 1 | use std::fmt; 2 | use std::io::Write; 3 | 4 | /// Output buffer/writer for `CodedOutputStream`. 5 | pub(crate) enum OutputTarget<'a> { 6 | Write(&'a mut dyn Write, Vec), 7 | Vec(&'a mut Vec), 8 | /// The buffer is passed as `&[u8]` to `CodedOutputStream` constructor 9 | /// and immediately converted to `buffer` field of `CodedOutputStream`, 10 | /// it is not needed to be stored here. 11 | /// Lifetime parameter of `CodedOutputStream` guarantees the buffer is valid 12 | /// during the lifetime of `CodedOutputStream`. 13 | Bytes, 14 | } 15 | 16 | impl<'a> fmt::Debug for OutputTarget<'a> { 17 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 18 | match self { 19 | OutputTarget::Write(_w, vec) => f 20 | .debug_struct("Write") 21 | .field("buf_len", &vec.len()) 22 | .field("buf_cap", &vec.capacity()) 23 | .finish_non_exhaustive(), 24 | OutputTarget::Vec(vec) => f 25 | .debug_struct("Vec") 26 | .field("len", &vec.len()) 27 | .field("cap", &vec.capacity()) 28 | .finish_non_exhaustive(), 29 | OutputTarget::Bytes => f.debug_tuple("Bytes").finish(), 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /protobuf/src/reflect/dynamic/optional.rs: -------------------------------------------------------------------------------- 1 | use crate::reflect::value::value_ref::ReflectValueMut; 2 | use crate::reflect::ReflectOptionalRef; 3 | use crate::reflect::ReflectValueBox; 4 | use crate::reflect::RuntimeType; 5 | 6 | #[derive(Debug, Clone)] 7 | pub(crate) struct DynamicOptional { 8 | elem: RuntimeType, 9 | value: Option, 10 | } 11 | 12 | impl DynamicOptional { 13 | pub(crate) fn none(elem: RuntimeType) -> DynamicOptional { 14 | DynamicOptional { elem, value: None } 15 | } 16 | 17 | pub(crate) fn mut_or_default(&mut self) -> ReflectValueMut { 18 | if let None = self.value { 19 | self.value = Some(self.elem.default_value_ref().to_box()); 20 | } 21 | self.value.as_mut().unwrap().as_value_mut() 22 | } 23 | 24 | pub(crate) fn clear(&mut self) { 25 | self.value = None; 26 | } 27 | 28 | pub(crate) fn set(&mut self, value: ReflectValueBox) { 29 | assert_eq!(value.get_type(), self.elem); 30 | self.value = Some(value); 31 | } 32 | 33 | pub(crate) fn reflect_singlar_ref(&self) -> ReflectOptionalRef { 34 | match &self.value { 35 | Some(value) => ReflectOptionalRef::some(value.as_value_ref()), 36 | None => ReflectOptionalRef::none(self.elem.clone()), 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /protobuf-parse/src/pure/parse_dependencies.rs: -------------------------------------------------------------------------------- 1 | use protobuf::descriptor::FileDescriptorProto; 2 | 3 | use crate::pure::convert::populate_dependencies; 4 | use crate::pure::model; 5 | use crate::pure::parser::ParserErrorWithLocation; 6 | 7 | /// Parse imports from a `.proto` file. 8 | /// 9 | /// The result is [`FileDescriptorProto`] object with only `*dependency` fields filled. 10 | pub fn parse_dependencies(content: &str) -> Result { 11 | let input = model::FileDescriptor::parse(content)?; 12 | let mut output = FileDescriptorProto::new(); 13 | populate_dependencies(&input, &mut output); 14 | Ok(output) 15 | } 16 | 17 | #[cfg(test)] 18 | mod test { 19 | #[test] 20 | fn parse_dependencies() { 21 | let deps = crate::pure::parse_dependencies::parse_dependencies( 22 | r" 23 | syntax = 'proto3'; 24 | 25 | import 'google/protobuf/field_mask.proto'; 26 | import public 'google/protobuf/struct.proto'; 27 | 28 | message IgnoreMe {} 29 | ", 30 | ) 31 | .unwrap(); 32 | assert_eq!( 33 | &[ 34 | "google/protobuf/field_mask.proto", 35 | "google/protobuf/struct.proto", 36 | ], 37 | &deps.dependency[..] 38 | ); 39 | assert_eq!(&[1], &deps.public_dependency[..]); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /test-crates/protobuf-test-common/src/dynamic.rs: -------------------------------------------------------------------------------- 1 | use protobuf::reflect::FileDescriptor; 2 | use protobuf::reflect::MessageDescriptor; 3 | use protobuf::MessageDyn; 4 | use protobuf::MessageFull; 5 | 6 | /// Recreate generated message file descriptor as dynamic descriptor. 7 | pub fn dynamic_descriptor_for_descriptor() -> MessageDescriptor { 8 | let file_descriptor = M::descriptor().file_descriptor().clone(); 9 | let dynamic_file_descriptor = FileDescriptor::new_dynamic( 10 | M::descriptor().file_descriptor_proto().clone(), 11 | file_descriptor.deps(), 12 | ) 13 | .unwrap(); 14 | 15 | // Find the dynamic version of the generated message. 16 | let dynamic_descriptor = dynamic_file_descriptor 17 | .message_by_package_relative_name(M::descriptor().name_to_package()) 18 | .unwrap(); 19 | 20 | // This descriptor is equivalent to `M::descriptor()`, but created dynamically 21 | // using descriptor data stored in generated files. 22 | dynamic_descriptor 23 | } 24 | 25 | /// Serialize message and parse it back as dynamic message. 26 | pub fn recreate_as_dynamic(m: &M) -> Box { 27 | let bytes = m.write_to_bytes().unwrap(); 28 | let dynamic_descriptor = dynamic_descriptor_for_descriptor::(); 29 | dynamic_descriptor.parse_from_bytes(&bytes).unwrap() 30 | } 31 | -------------------------------------------------------------------------------- /protobuf-parse/src/protobuf_path.rs: -------------------------------------------------------------------------------- 1 | use std::fmt; 2 | 3 | use crate::protobuf_abs_path::ProtobufAbsPath; 4 | use crate::protobuf_rel_path::ProtobufRelPath; 5 | 6 | /// Protobuf identifier can be absolute or relative. 7 | #[derive(Debug, Eq, PartialEq, Clone, Hash)] 8 | pub(crate) enum ProtobufPath { 9 | Abs(ProtobufAbsPath), 10 | Rel(ProtobufRelPath), 11 | } 12 | 13 | impl ProtobufPath { 14 | pub fn new>(path: S) -> ProtobufPath { 15 | let path = path.into(); 16 | if path.starts_with('.') { 17 | ProtobufPath::Abs(ProtobufAbsPath::new(path)) 18 | } else { 19 | ProtobufPath::Rel(ProtobufRelPath::new(path)) 20 | } 21 | } 22 | 23 | pub fn _resolve(&self, package: &ProtobufAbsPath) -> ProtobufAbsPath { 24 | match self { 25 | ProtobufPath::Abs(p) => p.clone(), 26 | ProtobufPath::Rel(p) => { 27 | let mut package = package.clone(); 28 | package.push_relative(p); 29 | package 30 | } 31 | } 32 | } 33 | } 34 | 35 | impl fmt::Display for ProtobufPath { 36 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 37 | match self { 38 | ProtobufPath::Abs(p) => write!(f, "{}", p), 39 | ProtobufPath::Rel(p) => write!(f, "{}", p), 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /protobuf/regenerate.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh -ex 2 | 3 | cd "$(dirname "$0")" 4 | 5 | die() { 6 | echo "$@" >&2 7 | exit 1 8 | } 9 | 10 | cargo build --manifest-path=../protobuf-codegen/Cargo.toml 11 | cargo build --manifest-path=../protoc-bin/Cargo.toml --bin protoc-bin-print-paths 12 | 13 | eval "$(cargo run --manifest-path=../protoc-bin/Cargo.toml --bin protoc-bin-print-paths)" 14 | 15 | test -n "$PROTOC" 16 | 17 | where_am_i=$( 18 | cd .. 19 | pwd 20 | ) 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-rs="$where_am_i/target/debug/protoc-gen-rs$exe_suffix" \ 36 | --rs_out tmp-generated \ 37 | --rs_opt 'inside_protobuf=true gen_mod_rs=false' \ 38 | -I../proto \ 39 | ../proto/google/protobuf/*.proto \ 40 | ../proto/google/protobuf/compiler/*.proto \ 41 | ../proto/rustproto.proto \ 42 | ../proto/doctest_pb.proto 43 | 44 | mv \ 45 | tmp-generated/descriptor.rs \ 46 | tmp-generated/plugin.rs \ 47 | tmp-generated/rustproto.rs \ 48 | tmp-generated/doctest_pb.rs \ 49 | src/ 50 | mv tmp-generated/well_known_types_mod.rs src/well_known_types/mod.rs 51 | mv tmp-generated/*.rs src/well_known_types/ 52 | 53 | # vim: set ts=4 sw=4 et: 54 | -------------------------------------------------------------------------------- /protobuf-codegen/src/gen/field/repeated.rs: -------------------------------------------------------------------------------- 1 | use crate::gen::field::elem::FieldElem; 2 | use crate::gen::file_and_mod::FileAndMod; 3 | use crate::gen::rust::snippets::EXPR_VEC_NEW; 4 | use crate::gen::rust_types_values::RustType; 5 | 6 | /// Repeated field can be `Vec` or `RepeatedField`. 7 | #[derive(Eq, PartialEq, Copy, Clone)] 8 | pub enum RepeatedFieldKind { 9 | Vec, 10 | } 11 | 12 | impl RepeatedFieldKind { 13 | fn wrap_element(&self, element_type: RustType) -> RustType { 14 | let element_type = Box::new(element_type); 15 | match self { 16 | RepeatedFieldKind::Vec => RustType::Vec(element_type), 17 | } 18 | } 19 | 20 | fn default(&self) -> String { 21 | match self { 22 | RepeatedFieldKind::Vec => EXPR_VEC_NEW.to_owned(), 23 | } 24 | } 25 | } 26 | 27 | #[derive(Clone)] 28 | pub(crate) struct RepeatedField<'a> { 29 | pub elem: FieldElem<'a>, 30 | pub packed: bool, 31 | } 32 | 33 | impl<'a> RepeatedField<'a> { 34 | pub(crate) fn kind(&self) -> RepeatedFieldKind { 35 | RepeatedFieldKind::Vec 36 | } 37 | 38 | pub(crate) fn rust_type(&self, reference: &FileAndMod) -> RustType { 39 | self.kind() 40 | .wrap_element(self.elem.rust_storage_elem_type(reference)) 41 | } 42 | 43 | pub(crate) fn default(&self) -> String { 44 | self.kind().default() 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /test-crates/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 | -------------------------------------------------------------------------------- /test-crates/protobuf-codegen-protoc-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 | -------------------------------------------------------------------------------- /protobuf/src/reflect/field/dynamic.rs: -------------------------------------------------------------------------------- 1 | use crate::message_dyn::MessageDyn; 2 | use crate::reflect::dynamic::DynamicMessage; 3 | use crate::reflect::FieldDescriptor; 4 | use crate::reflect::ReflectFieldRef; 5 | use crate::reflect::ReflectMapMut; 6 | use crate::reflect::ReflectRepeatedMut; 7 | use crate::reflect::ReflectValueBox; 8 | 9 | pub(crate) struct DynamicFieldDescriptorRef<'a> { 10 | pub(crate) field: &'a FieldDescriptor, 11 | } 12 | 13 | impl<'a> DynamicFieldDescriptorRef<'a> { 14 | pub(crate) fn get_reflect<'b>(&self, message: &'b dyn MessageDyn) -> ReflectFieldRef<'b> { 15 | DynamicMessage::downcast_ref(message).get_reflect(&self.field) 16 | } 17 | 18 | pub(crate) fn mut_repeated<'b>( 19 | &self, 20 | message: &'b mut dyn MessageDyn, 21 | ) -> ReflectRepeatedMut<'b> { 22 | DynamicMessage::downcast_mut(message).mut_repeated(&self.field) 23 | } 24 | 25 | pub(crate) fn mut_map<'b>(&self, message: &'b mut dyn MessageDyn) -> ReflectMapMut<'b> { 26 | DynamicMessage::downcast_mut(message).mut_map(&self.field) 27 | } 28 | 29 | pub(crate) fn set_field(&self, message: &mut dyn MessageDyn, value: ReflectValueBox) { 30 | DynamicMessage::downcast_mut(message).set_field(&self.field, value) 31 | } 32 | 33 | pub(crate) fn clear_field(&self, message: &mut dyn MessageDyn) { 34 | DynamicMessage::downcast_mut(message).clear_field(&self.field) 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /test-crates/protobuf-test-common/src/interop.rs: -------------------------------------------------------------------------------- 1 | use std::io::Read; 2 | use std::io::Write; 3 | use std::process; 4 | 5 | /// Invoke `interop` binary, pass given data as stdin, return stdout. 6 | pub fn interop_command(command: &str, stdin: &[u8]) -> Vec { 7 | let mut interop = process::Command::new("../test-crates/interop/cxx/interop") 8 | .args(&[command]) 9 | .stdin(process::Stdio::piped()) 10 | .stdout(process::Stdio::piped()) 11 | .stderr(process::Stdio::inherit()) 12 | .spawn() 13 | .expect("interop"); 14 | 15 | interop 16 | .stdin 17 | .take() 18 | .unwrap() 19 | .write_all(stdin) 20 | .expect("write to process"); 21 | 22 | let mut stdout = Vec::new(); 23 | interop 24 | .stdout 25 | .take() 26 | .unwrap() 27 | .read_to_end(&mut stdout) 28 | .expect("read json"); 29 | 30 | let exit_status = interop.wait().expect("wait_with_output"); 31 | assert!(exit_status.success(), "{}", exit_status); 32 | 33 | stdout 34 | } 35 | 36 | /// Decode binary protobuf, encode as JSON. 37 | pub fn interop_json_encode(bytes: &[u8]) -> String { 38 | let json = interop_command("json-encode", bytes); 39 | String::from_utf8(json).expect("UTF-8") 40 | } 41 | 42 | /// Decode JSON, encode as binary protobuf. 43 | pub fn interop_json_decode(s: &str) -> Vec { 44 | interop_command("json-decode", s.as_bytes()) 45 | } 46 | -------------------------------------------------------------------------------- /protobuf-codegen/src/gen/rust/ident_with_path.rs: -------------------------------------------------------------------------------- 1 | use std::fmt; 2 | 3 | use crate::gen::rust::component::RustPathComponent; 4 | use crate::gen::rust::ident::RustIdent; 5 | use crate::gen::rust::path::RustPath; 6 | 7 | #[derive(Eq, PartialEq, Debug, Clone)] 8 | pub(crate) struct RustIdentWithPath { 9 | pub path: RustPath, 10 | pub ident: RustIdent, 11 | } 12 | 13 | impl RustIdentWithPath { 14 | pub fn new(s: String) -> RustIdentWithPath { 15 | let mut path = RustPath::from(s); 16 | let ident = match path.path.path.pop() { 17 | None => panic!("empty path"), 18 | Some(RustPathComponent::Ident(ident)) => ident, 19 | Some(RustPathComponent::Keyword(kw)) => { 20 | panic!("last path component is a keyword: {}", kw) 21 | } 22 | }; 23 | RustIdentWithPath { path, ident } 24 | } 25 | 26 | pub fn prepend_ident(&mut self, ident: RustIdent) { 27 | self.path.prepend_ident(ident) 28 | } 29 | 30 | pub fn to_path(&self) -> RustPath { 31 | self.path.clone().append_ident(self.ident.clone()) 32 | } 33 | } 34 | 35 | impl> From for RustIdentWithPath { 36 | fn from(s: S) -> Self { 37 | RustIdentWithPath::new(s.into()) 38 | } 39 | } 40 | 41 | impl fmt::Display for RustIdentWithPath { 42 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 43 | fmt::Display::fmt(&self.to_path(), f) 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /protobuf/src/reflect/service/index.rs: -------------------------------------------------------------------------------- 1 | use crate::descriptor::MethodDescriptorProto; 2 | use crate::descriptor::ServiceDescriptorProto; 3 | use crate::reflect::field::index::ForwardProtobufTypeBox; 4 | use crate::reflect::file::building::FileDescriptorBuilding; 5 | 6 | #[derive(Debug)] 7 | pub(crate) struct ServiceIndex { 8 | pub(crate) methods: Vec, 9 | } 10 | 11 | impl ServiceIndex { 12 | pub(crate) fn index( 13 | proto: &ServiceDescriptorProto, 14 | building: &FileDescriptorBuilding, 15 | ) -> crate::Result { 16 | let methods = proto 17 | .method 18 | .iter() 19 | .map(|method| MethodIndex::index(method, building)) 20 | .collect::>>()?; 21 | Ok(ServiceIndex { methods }) 22 | } 23 | } 24 | 25 | #[derive(Debug)] 26 | pub(crate) struct MethodIndex { 27 | pub(crate) input_type: ForwardProtobufTypeBox, 28 | pub(crate) output_type: ForwardProtobufTypeBox, 29 | } 30 | 31 | impl MethodIndex { 32 | pub(crate) fn index( 33 | proto: &MethodDescriptorProto, 34 | building: &FileDescriptorBuilding, 35 | ) -> crate::Result { 36 | let input_type = building.resolve_message(proto.input_type())?; 37 | let output_type = building.resolve_message(proto.output_type())?; 38 | Ok(MethodIndex { 39 | input_type, 40 | output_type, 41 | }) 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to rust-protobuf 2 | 3 | ## I just want to ask a question 4 | 5 | Feel free to open an issue to ask a question, the volume of questions is low, 6 | so it's OK at the moment. But please don't expect a prompt answer. 7 | 8 | ## I have found a bug 9 | 10 | Please open an [issue](https://github.com/stepancheg/rust-protobuf/issues). When reporting a bug please include minimal example 11 | providing as much information as possible. In particular, please specify: 12 | 13 | * exact proto file 14 | * generated file 15 | * rust-protobuf version 16 | * command which was used to generate code (ideally, temporary standalone repository) 17 | * what is version of `protoc` command 18 | * what is operating system 19 | 20 | ## Tests 21 | 22 | Most of code changes should be accompanied by tests. 23 | 24 | Most tests can be executed by invoking `cargo test` in `protobuf-test` directory. 25 | 26 | ## Codegen 27 | 28 | If you change code generator, tests will check that code generator works correctly. 29 | 30 | However, before submitting a PR, it's necessary to regenerate generated files 31 | shipped with rust-protobuf, notably, `descriptor.rs`. 32 | 33 | This can be done by invoking a script `protobuf/regenerate.sh`. 34 | 35 | ## Performance improvements 36 | 37 | Are always welcome, especially if they are backward-compatible. 38 | 39 | ## Help wanted 40 | 41 | Most of all documentation is needed, any changes to rustdoc or markdown pages on GitHub are welcome. 42 | -------------------------------------------------------------------------------- /protobuf/src/reflect/acc/mod.rs: -------------------------------------------------------------------------------- 1 | use crate::message_dyn::MessageDyn; 2 | use crate::reflect::acc::v2::AccessorV2; 3 | use crate::reflect::ReflectFieldRef; 4 | 5 | pub(crate) mod v2; 6 | 7 | #[derive(Debug)] 8 | pub(crate) enum GeneratedFieldAccessor { 9 | V2(AccessorV2), 10 | } 11 | 12 | /// Accessor object is constructed in generated code. 13 | /// Should not be used directly. 14 | #[derive(Debug)] 15 | pub struct FieldAccessor { 16 | pub(crate) _name: &'static str, 17 | pub(crate) accessor: GeneratedFieldAccessor, 18 | } 19 | 20 | impl GeneratedFieldAccessor { 21 | pub(crate) fn get_reflect<'a>(&self, m: &'a dyn MessageDyn) -> ReflectFieldRef<'a> { 22 | match self { 23 | GeneratedFieldAccessor::V2(AccessorV2::Singular(ref a)) => { 24 | ReflectFieldRef::Optional(a.accessor.get_field(m)) 25 | } 26 | GeneratedFieldAccessor::V2(AccessorV2::Repeated(ref a)) => { 27 | ReflectFieldRef::Repeated(a.accessor.get_repeated(m)) 28 | } 29 | GeneratedFieldAccessor::V2(AccessorV2::Map(ref a)) => { 30 | ReflectFieldRef::Map(a.accessor.get_reflect(m)) 31 | } 32 | } 33 | } 34 | } 35 | 36 | impl FieldAccessor { 37 | pub(crate) fn new(name: &'static str, accessor: AccessorV2) -> FieldAccessor { 38 | FieldAccessor { 39 | _name: name, 40 | accessor: GeneratedFieldAccessor::V2(accessor), 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /test-crates/protobuf-codegen-protoc-test/src/common/v2/test_basic_pb.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto2"; 2 | 3 | import "rustproto.proto"; 4 | option (rustproto.generate_accessors_all) = true; 5 | 6 | 7 | package basic; 8 | 9 | message Test1 { 10 | required int32 a = 1; 11 | } 12 | 13 | message Test2 { 14 | required string b = 2; 15 | } 16 | 17 | message Test3 { 18 | required Test1 c = 3; 19 | } 20 | 21 | message TestRecursion { 22 | repeated TestRecursion children = 1; 23 | } 24 | 25 | message Test4 { 26 | repeated int32 d = 4 [packed=true]; 27 | } 28 | 29 | message TestEmpty { 30 | optional int32 foo = 10; 31 | } 32 | 33 | message TestUnknownFields { 34 | required int32 a = 1; 35 | } 36 | 37 | // just check it compiles 38 | message TestSelfReference { 39 | required TestSelfReference r1 = 1; 40 | optional TestSelfReference r2 = 2; 41 | } 42 | 43 | message TestDefaultInstanceField { 44 | optional string s = 1; 45 | } 46 | 47 | message TestDefaultInstance { 48 | optional TestDefaultInstanceField field = 1; 49 | } 50 | 51 | message TestDescriptor { 52 | optional int32 stuff = 10; 53 | } 54 | 55 | enum TestEnumDescriptor { 56 | UNDEFINED = 0; 57 | RED = 1; 58 | BLUE = 2; 59 | GREEN = 3; 60 | } 61 | 62 | message TestInvalidTag { 63 | } 64 | 65 | message TestTruncated { 66 | repeated fixed32 ints = 2 [packed=true]; 67 | } 68 | 69 | message TestBugSint { 70 | optional sint32 s32 = 1; 71 | optional sint64 s64 = 2; 72 | } 73 | -------------------------------------------------------------------------------- /test-crates/protobuf-codegen-protoc-test/src/common/v2/test_dynamic_repeated_get_set.rs: -------------------------------------------------------------------------------- 1 | use protobuf::reflect::FileDescriptor; 2 | use protobuf::reflect::ReflectValueBox; 3 | 4 | use super::test_dynamic_repeated_get_set_pb; 5 | 6 | fn dynamic_file_descriptor() -> FileDescriptor { 7 | FileDescriptor::new_dynamic( 8 | test_dynamic_repeated_get_set_pb::file_descriptor() 9 | .proto() 10 | .clone(), 11 | &[], 12 | ) 13 | .unwrap() 14 | } 15 | 16 | fn do_test_repeated(file_descriptor: &FileDescriptor) { 17 | let m = file_descriptor 18 | .message_by_package_relative_name("ForDynamicRepeatedTest") 19 | .unwrap(); 20 | let f = m.field_by_name("ii").unwrap(); 21 | let mut m = m.new_instance(); 22 | assert!(f.get_repeated(&*m).is_empty()); 23 | assert!(f.mut_repeated(&mut *m).is_empty()); 24 | f.mut_repeated(&mut *m).push(ReflectValueBox::U32(19)); 25 | f.mut_repeated(&mut *m).push(ReflectValueBox::U32(17)); 26 | assert_eq!(2, f.get_repeated(&*m).len()); 27 | assert_eq!(ReflectValueBox::U32(17), f.get_repeated(&*m).get(1)); 28 | assert_eq!( 29 | &[ReflectValueBox::U32(19), ReflectValueBox::U32(17)][..], 30 | &f.get_repeated(&*m) 31 | ); 32 | } 33 | 34 | #[test] 35 | fn generated_repeated() { 36 | do_test_repeated(&dynamic_file_descriptor()); 37 | } 38 | 39 | #[test] 40 | fn dynamic_repeated() { 41 | do_test_repeated(&test_dynamic_repeated_get_set_pb::file_descriptor()); 42 | } 43 | -------------------------------------------------------------------------------- /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 | /// Create a new `CachedSize` object. 19 | pub const fn new() -> CachedSize { 20 | CachedSize { 21 | size: AtomicUsize::new(0), 22 | } 23 | } 24 | 25 | /// Get cached size 26 | pub fn get(&self) -> u32 { 27 | self.size.load(Ordering::Relaxed) as u32 28 | } 29 | 30 | /// Set cached size 31 | pub fn set(&self, size: u32) { 32 | self.size.store(size as usize, Ordering::Relaxed) 33 | } 34 | } 35 | 36 | impl Clone for CachedSize { 37 | fn clone(&self) -> CachedSize { 38 | CachedSize { 39 | size: AtomicUsize::new(self.size.load(Ordering::Relaxed)), 40 | } 41 | } 42 | } 43 | 44 | impl PartialEq for CachedSize { 45 | fn eq(&self, _other: &CachedSize) -> bool { 46 | true 47 | } 48 | } 49 | 50 | impl Eq for CachedSize {} 51 | 52 | impl Hash for CachedSize { 53 | fn hash(&self, _state: &mut H) { 54 | // ignore cached size in cache computation 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /protobuf-support/src/lexer/token.rs: -------------------------------------------------------------------------------- 1 | use crate::lexer::json_number_lit::JsonNumberLit; 2 | use crate::lexer::lexer_impl::LexerError; 3 | use crate::lexer::lexer_impl::LexerResult; 4 | use crate::lexer::loc::Loc; 5 | use crate::lexer::num_lit::NumLit; 6 | use crate::lexer::str_lit::StrLit; 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-examples/customize-serde/build.rs: -------------------------------------------------------------------------------- 1 | use protobuf::descriptor::field_descriptor_proto::Type; 2 | use protobuf::reflect::FieldDescriptor; 3 | use protobuf::reflect::MessageDescriptor; 4 | use protobuf_codegen::Codegen; 5 | use protobuf_codegen::Customize; 6 | use protobuf_codegen::CustomizeCallback; 7 | 8 | fn main() { 9 | struct GenSerde; 10 | 11 | impl CustomizeCallback for GenSerde { 12 | fn message(&self, _message: &MessageDescriptor) -> Customize { 13 | Customize::default().before("#[derive(::serde::Serialize, ::serde::Deserialize)]") 14 | } 15 | 16 | fn field(&self, field: &FieldDescriptor) -> Customize { 17 | if field.proto().type_() == Type::TYPE_ENUM { 18 | // `EnumOrUnknown` is not a part of rust-protobuf, so external serializer is needed. 19 | Customize::default().before( 20 | "#[serde(serialize_with = \"crate::serialize_enum_or_unknown\", deserialize_with = \"crate::deserialize_enum_or_unknown\")]") 21 | } else { 22 | Customize::default() 23 | } 24 | } 25 | 26 | fn special_field(&self, _message: &MessageDescriptor, _field: &str) -> Customize { 27 | Customize::default().before("#[serde(skip)]") 28 | } 29 | } 30 | 31 | Codegen::new() 32 | .cargo_out_dir("protos") 33 | .include("src") 34 | .inputs(&["src/customize_example.proto"]) 35 | .customize_callback(GenSerde) 36 | .run_from_script(); 37 | } 38 | -------------------------------------------------------------------------------- /protobuf-parse/src/rel_path.rs: -------------------------------------------------------------------------------- 1 | use std::ops::Deref; 2 | use std::path::Path; 3 | use std::path::PathBuf; 4 | 5 | /// Wrapper for `Path` that asserts that the path is relative. 6 | #[repr(transparent)] 7 | pub(crate) struct RelPath { 8 | path: Path, 9 | } 10 | 11 | /// Wrapper for `PathBuf` that asserts that the path is relative. 12 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] 13 | pub(crate) struct _RelPathBuf { 14 | path: PathBuf, 15 | } 16 | 17 | impl RelPath { 18 | pub(crate) fn _new(path: &Path) -> &RelPath { 19 | assert!( 20 | !path.is_absolute(), 21 | "path must be relative: {}", 22 | path.display() 23 | ); 24 | unsafe { &*(path as *const Path as *const RelPath) } 25 | } 26 | 27 | pub(crate) fn _to_owned(&self) -> _RelPathBuf { 28 | _RelPathBuf { 29 | path: self.path.to_owned(), 30 | } 31 | } 32 | } 33 | 34 | impl _RelPathBuf { 35 | pub(crate) fn _new(path: PathBuf) -> _RelPathBuf { 36 | assert!( 37 | !path.is_absolute(), 38 | "path must be relative: {}", 39 | path.display() 40 | ); 41 | _RelPathBuf { path } 42 | } 43 | } 44 | 45 | impl Deref for RelPath { 46 | type Target = Path; 47 | 48 | fn deref(&self) -> &Self::Target { 49 | &self.path 50 | } 51 | } 52 | 53 | impl Deref for _RelPathBuf { 54 | type Target = RelPath; 55 | 56 | fn deref(&self) -> &Self::Target { 57 | RelPath::_new(&self.path) 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /protobuf/src/reflect/name.rs: -------------------------------------------------------------------------------- 1 | pub(crate) fn concat_paths(a: &str, b: &str) -> String { 2 | if a.is_empty() { 3 | b.to_owned() 4 | } else if b.is_empty() { 5 | b.to_owned() 6 | } else { 7 | format!("{}.{}", a, b) 8 | } 9 | } 10 | 11 | pub(crate) fn protobuf_name_starts_with_package<'a>( 12 | name: &'a str, 13 | package: &str, 14 | ) -> Option<&'a str> { 15 | assert!( 16 | !package.starts_with("."), 17 | "package must not start with dot: {}", 18 | package 19 | ); 20 | 21 | assert!( 22 | name.starts_with("."), 23 | "full name must start with dot: {}", 24 | name 25 | ); 26 | let name = &name[1..]; 27 | // assert!(!name.starts_with("."), "full name must not start with dot: {}", name); 28 | 29 | if package.is_empty() { 30 | Some(name) 31 | } else { 32 | if name.starts_with(package) { 33 | let rem = &name[package.len()..]; 34 | if rem.starts_with(".") { 35 | Some(&rem[1..]) 36 | } else { 37 | None 38 | } 39 | } else { 40 | None 41 | } 42 | } 43 | } 44 | 45 | #[test] 46 | fn test_protobuf_name_starts_with_package() { 47 | assert_eq!( 48 | Some("bar"), 49 | protobuf_name_starts_with_package(".foo.bar", "foo") 50 | ); 51 | assert_eq!(None, protobuf_name_starts_with_package(".foo", "foo")); 52 | assert_eq!(Some("foo"), protobuf_name_starts_with_package(".foo", "")); 53 | } 54 | -------------------------------------------------------------------------------- /test-crates/protobuf-codegen-protoc-test/src/v2/test_reflect_default.rs: -------------------------------------------------------------------------------- 1 | use protobuf::EnumOrUnknown; 2 | use protobuf::MessageFull; 3 | 4 | use super::test_reflect_default_pb::*; 5 | 6 | #[test] 7 | fn test_regular() { 8 | let m = TestReflectDefault::new(); 9 | 10 | let descriptor = TestReflectDefault::descriptor(); 11 | 12 | let i = descriptor.field_by_name("i").unwrap(); 13 | assert_eq!(10, i.get_singular_field_or_default(&m).to_i32().unwrap()); 14 | 15 | let s = descriptor.field_by_name("s").unwrap(); 16 | assert_eq!("sss", s.get_singular_field_or_default(&m).to_str().unwrap()); 17 | 18 | let e = descriptor.field_by_name("e").unwrap(); 19 | assert_eq!( 20 | EnumOrUnknown::new(Fruit::BANANA), 21 | e.get_singular_field_or_default(&m) 22 | .downcast_clone() 23 | .unwrap() 24 | ); 25 | } 26 | 27 | #[test] 28 | fn test_oneof() { 29 | let m = TestReflectDefault::new(); 30 | 31 | let descriptor = TestReflectDefault::descriptor(); 32 | 33 | let i = descriptor.field_by_name("oi").unwrap(); 34 | assert_eq!(10, i.get_singular_field_or_default(&m).to_i32().unwrap()); 35 | 36 | let s = descriptor.field_by_name("os").unwrap(); 37 | assert_eq!("sss", s.get_singular_field_or_default(&m).to_str().unwrap()); 38 | 39 | let e = descriptor.field_by_name("oe").unwrap(); 40 | assert_eq!( 41 | EnumOrUnknown::new(Fruit::BANANA), 42 | e.get_singular_field_or_default(&m) 43 | .downcast_clone() 44 | .unwrap() 45 | ); 46 | } 47 | -------------------------------------------------------------------------------- /test-crates/protobuf-codegen-protoc-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/duration.proto"; 5 | import "google/protobuf/field_mask.proto"; 6 | import "google/protobuf/struct.proto"; 7 | import "google/protobuf/timestamp.proto"; 8 | import "google/protobuf/wrappers.proto"; 9 | 10 | import "rustproto.proto"; 11 | option (rustproto.generate_accessors_all) = true; 12 | 13 | 14 | message TestFmtJsonWellKnownTypes { 15 | optional .google.protobuf.Duration duration = 3; 16 | optional .google.protobuf.Timestamp timestamp = 4; 17 | optional .google.protobuf.FieldMask field_mask = 5; 18 | repeated .google.protobuf.NullValue null_values = 10; 19 | optional .google.protobuf.Value value = 12; 20 | optional .google.protobuf.ListValue list_value = 13; 21 | optional .google.protobuf.Struct struct_value = 14; 22 | optional .google.protobuf.Any any_value = 15; 23 | 24 | optional .google.protobuf.DoubleValue double_value = 31; 25 | optional .google.protobuf.FloatValue float_value = 32; 26 | optional .google.protobuf.Int64Value int64_value = 33; 27 | optional .google.protobuf.UInt64Value uint64_value = 34; 28 | optional .google.protobuf.Int32Value int32_value = 35; 29 | optional .google.protobuf.UInt32Value uint32_value = 36; 30 | optional .google.protobuf.BoolValue bool_value = 37; 31 | optional .google.protobuf.StringValue string_value = 38; 32 | optional .google.protobuf.BytesValue bytes_value = 39; 33 | } 34 | -------------------------------------------------------------------------------- /protobuf-parse/src/case_convert.rs: -------------------------------------------------------------------------------- 1 | // copy-paste from Google Protobuf 2 | // must be kept in sync with Google for JSON interop 3 | #[doc(hidden)] 4 | pub fn camel_case(input: &str) -> String { 5 | let mut capitalize_next = true; 6 | let mut result = String::new(); 7 | result.reserve(input.len()); 8 | 9 | for c in input.chars() { 10 | if c == '_' { 11 | capitalize_next = true; 12 | } else if capitalize_next { 13 | result.push(c.to_ascii_uppercase()); 14 | capitalize_next = false; 15 | } else { 16 | result.push(c); 17 | } 18 | } 19 | 20 | result 21 | } 22 | 23 | #[doc(hidden)] 24 | pub fn snake_case(input: &str) -> String { 25 | let mut result = String::new(); 26 | 27 | let mut last_lower = false; 28 | 29 | for c in input.chars() { 30 | if c.is_ascii_uppercase() && last_lower { 31 | result.push('_'); 32 | } 33 | result.push(c.to_ascii_lowercase()); 34 | last_lower = c.is_lowercase(); 35 | } 36 | 37 | result 38 | } 39 | 40 | #[cfg(test)] 41 | mod test { 42 | use super::*; 43 | 44 | #[test] 45 | fn test_camel_case() { 46 | assert_eq!("FooBarBazQuxQUUX", camel_case("foo_barBaz_QuxQUUX")); 47 | assert_eq!("FooBarBazQuxQUUX", camel_case("Foo_barBaz_QuxQUUX")); 48 | } 49 | 50 | #[test] 51 | fn test_snake_case() { 52 | assert_eq!("foo_bar_baz_qux_quux", snake_case("foo_barBaz_QuxQUUX")); 53 | assert_eq!("foo_bar_baz_qux_quux", snake_case("Foo_barBaz_QuxQUUX")); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /protobuf-parse/src/lib.rs: -------------------------------------------------------------------------------- 1 | //! # Parse `.proto` files 2 | //! 3 | //! Parse `.proto` file definitions, **not** the protobuf text format serialization. 4 | //! 5 | //! Files can be parsed using pure Rust parser (mod `pure`) 6 | //! or using the `protoc` command (mod `protoc`). 7 | //! 8 | //! This crate is not meant to be used directly, but rather through the `protobuf-codegen` crate. 9 | //! If you think this crate might be useful to you, 10 | //! please [consider creating an issue](https://github.com/stepancheg/rust-protobuf/issues/new), 11 | //! until that this crate is considered to have **no stable API**. 12 | 13 | extern crate core; 14 | 15 | mod case_convert; 16 | mod parse_and_typecheck; 17 | mod parser; 18 | mod path; 19 | mod proto; 20 | mod proto_path; 21 | mod protobuf_abs_path; 22 | mod protobuf_ident; 23 | mod protobuf_path; 24 | mod protobuf_rel_path; 25 | pub(crate) mod protoc; 26 | pub mod pure; 27 | mod rel_path; 28 | mod test_against_protobuf_protos; 29 | mod which_parser; 30 | 31 | // Public API 32 | // Non-public API used by codegen crate. 33 | pub use case_convert::*; 34 | pub use parse_and_typecheck::*; 35 | pub use parser::Parser; 36 | pub use proto_path::*; 37 | use protobuf::reflect::FileDescriptor; 38 | pub use protobuf_abs_path::*; 39 | pub use protobuf_ident::*; 40 | pub use protobuf_rel_path::*; 41 | 42 | use crate::pure::model; 43 | 44 | #[derive(Clone)] 45 | pub(crate) struct FileDescriptorPair { 46 | pub(crate) parsed: model::FileDescriptor, 47 | pub(crate) descriptor_proto: protobuf::descriptor::FileDescriptorProto, 48 | pub(crate) descriptor: FileDescriptor, 49 | } 50 | -------------------------------------------------------------------------------- /protobuf-codegen/src/gen/strx.rs: -------------------------------------------------------------------------------- 1 | pub fn remove_to<'s, P>(s: &'s str, pattern: P) -> &'s str 2 | where 3 | P: Fn(char) -> bool, 4 | { 5 | match s.rfind(pattern) { 6 | Some(pos) => &s[(pos + 1)..], 7 | None => s, 8 | } 9 | } 10 | 11 | pub fn remove_suffix<'s>(s: &'s str, suffix: &str) -> &'s str { 12 | if !s.ends_with(suffix) { 13 | s 14 | } else { 15 | &s[..(s.len() - suffix.len())] 16 | } 17 | } 18 | 19 | pub fn capitalize(s: &str) -> String { 20 | if s.is_empty() { 21 | return String::new(); 22 | } 23 | let mut char_indices = s.char_indices(); 24 | char_indices.next().unwrap(); 25 | match char_indices.next() { 26 | None => s.to_uppercase(), 27 | Some((i, _)) => s[..i].to_uppercase() + &s[i..], 28 | } 29 | } 30 | 31 | #[cfg(test)] 32 | mod test { 33 | 34 | use super::capitalize; 35 | use super::remove_suffix; 36 | use super::remove_to; 37 | 38 | #[test] 39 | fn test_remove_to() { 40 | assert_eq!("aaa", remove_to("aaa", |c| c == '.')); 41 | assert_eq!("bbb", remove_to("aaa.bbb", |c| c == '.')); 42 | assert_eq!("ccc", remove_to("aaa.bbb.ccc", |c| c == '.')); 43 | } 44 | 45 | #[test] 46 | fn test_remove_suffix() { 47 | assert_eq!("bbb", remove_suffix("bbbaaa", "aaa")); 48 | assert_eq!("aaa", remove_suffix("aaa", "bbb")); 49 | } 50 | 51 | #[test] 52 | fn test_capitalize() { 53 | assert_eq!("", capitalize("")); 54 | assert_eq!("F", capitalize("f")); 55 | assert_eq!("Foo", capitalize("foo")); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /test-crates/protobuf-test-common/src/json_tests.rs: -------------------------------------------------------------------------------- 1 | use protobuf::reflect::ReflectEqMode; 2 | use protobuf::text_format; 3 | use protobuf::MessageDyn; 4 | 5 | pub fn test_json_print_parse_message(s: &str, m: &dyn MessageDyn) { 6 | assert_eq!( 7 | s, 8 | protobuf_json_mapping::print_to_string(m).expect("print_to_string") 9 | ); 10 | 11 | test_json_parse_message(s, m); 12 | } 13 | 14 | pub fn test_json_parse_message(s: &str, m: &dyn MessageDyn) { 15 | let descriptor = m.descriptor_dyn(); 16 | 17 | let mut new = descriptor.new_instance(); 18 | protobuf_json_mapping::merge_from_str(&mut *new, s).expect("parse"); 19 | assert!( 20 | m.reflect_eq_dyn(&*new, &ReflectEqMode::nan_equal()), 21 | "{:?} should be == {:?}", 22 | text_format::print_to_string(m), 23 | text_format::print_to_string(&*new) 24 | ); 25 | } 26 | 27 | /// Print message to string, parse the string, 28 | /// then check resulting message is equal to the original. 29 | pub fn test_json_message(m: &dyn MessageDyn) { 30 | let descriptor = m.descriptor_dyn(); 31 | 32 | let s = protobuf_json_mapping::print_to_string(m).expect("print_to_string"); 33 | let mut new = descriptor.new_instance(); 34 | protobuf_json_mapping::merge_from_str(&mut *new, &s).expect(&format!( 35 | "failed to parse serialized: {}; from message: {:?}", 36 | s, m 37 | )); 38 | assert!( 39 | m.reflect_eq_dyn(&*new, &ReflectEqMode::nan_equal()), 40 | "{:?} should be == {:?}", 41 | text_format::print_to_string(m), 42 | text_format::print_to_string(&*new) 43 | ); 44 | } 45 | -------------------------------------------------------------------------------- /test-crates/perftest/bytes/build.rs: -------------------------------------------------------------------------------- 1 | use std::env; 2 | use std::io::Read; 3 | use std::process; 4 | 5 | use protobuf_codegen::Codegen; 6 | use protobuf_codegen::Customize; 7 | 8 | fn generate_protos() { 9 | Codegen::new() 10 | .pure() 11 | .out_dir("src") 12 | .input("src/messages.proto") 13 | .includes(&["src", "../../proto"]) 14 | .customize(Customize::default().gen_mod_rs(false)) 15 | .run_from_script(); 16 | } 17 | 18 | // % rustc +stable --version 19 | // rustc 1.26.0 (a77568041 2018-05-07) 20 | // % rustc +beta --version 21 | // rustc 1.27.0-beta.1 (03fb2f447 2018-05-09) 22 | // % rustc +nightly --version 23 | // rustc 1.27.0-nightly (acd3871ba 2018-05-10) 24 | fn version_is_nightly(version: &str) -> bool { 25 | version.contains("nightly") 26 | } 27 | 28 | fn export_rustc_cfg() { 29 | let rustc = env::var("RUSTC").expect("RUSTC unset"); 30 | 31 | let mut child = process::Command::new(rustc) 32 | .args(&["--version"]) 33 | .stdin(process::Stdio::null()) 34 | .stdout(process::Stdio::piped()) 35 | .spawn() 36 | .expect("spawn rustc"); 37 | 38 | let mut rustc_version = String::new(); 39 | 40 | child 41 | .stdout 42 | .as_mut() 43 | .expect("stdout") 44 | .read_to_string(&mut rustc_version) 45 | .expect("read_to_string"); 46 | assert!(child.wait().expect("wait").success()); 47 | 48 | if version_is_nightly(&rustc_version) { 49 | println!("cargo:rustc-cfg=rustc_nightly"); 50 | } 51 | } 52 | 53 | fn main() { 54 | generate_protos(); 55 | 56 | export_rustc_cfg(); 57 | } 58 | --------------------------------------------------------------------------------