PROTOBUF_SYNC_PIPER
pull/10526/head
Mike Kruskal 2 years ago
commit 1595417dd3
  1. 1
      .bazelignore
  2. 6
      .gitmodules
  3. 1
      BUILD.bazel
  4. 1
      README.md
  5. 9
      WORKSPACE
  6. 1
      build_defs/cpp_opts.bzl
  7. 2
      cmake/abseil-cpp.cmake
  8. 3
      cmake/libprotobuf-lite.cmake
  9. 3
      cmake/libprotobuf.cmake
  10. 3
      cmake/libprotoc.cmake
  11. 43
      conformance/README.md
  12. 63
      conformance/binary_json_conformance_suite.cc
  13. 26
      conformance/conformance_cpp.cc
  14. 12
      conformance/conformance_test.cc
  15. 6
      conformance/conformance_test.h
  16. 2
      conformance/conformance_test_runner.cc
  17. 8
      conformance/text_format_conformance_suite.cc
  18. 2
      csharp/BUILD.bazel
  19. 11
      csharp/generate_protos.sh
  20. 4
      csharp/protos/unittest_issues.proto
  21. 87
      csharp/src/Google.Protobuf.Benchmarks/BenchmarkDatasetConfig.cs
  22. 2632
      csharp/src/Google.Protobuf.Benchmarks/BenchmarkMessage1Proto3.cs
  23. 325
      csharp/src/Google.Protobuf.Benchmarks/Benchmarks.cs
  24. 72
      csharp/src/Google.Protobuf.Benchmarks/ByteStringBenchmark.cs
  25. 26
      csharp/src/Google.Protobuf.Benchmarks/Google.Protobuf.Benchmarks.csproj
  26. 124
      csharp/src/Google.Protobuf.Benchmarks/GoogleMessageBenchmark.cs
  27. 258
      csharp/src/Google.Protobuf.Benchmarks/ParseMessagesBenchmark.cs
  28. 536
      csharp/src/Google.Protobuf.Benchmarks/ParseRawPrimitivesBenchmark.cs
  29. 47
      csharp/src/Google.Protobuf.Benchmarks/Program.cs
  30. 9604
      csharp/src/Google.Protobuf.Benchmarks/WrapperBenchmarkMessages.cs
  31. 198
      csharp/src/Google.Protobuf.Benchmarks/WriteMessagesBenchmark.cs
  32. 516
      csharp/src/Google.Protobuf.Benchmarks/WriteRawPrimitivesBenchmark.cs
  33. 237
      csharp/src/Google.Protobuf.Benchmarks/wrapper_benchmark_messages.proto
  34. 78
      csharp/src/Google.Protobuf.Test.TestProtos/UnittestIssues.cs
  35. 12
      csharp/src/Google.Protobuf.Test/Collections/RepeatedFieldTest.cs
  36. 21
      csharp/src/Google.Protobuf.Test/DeprecatedMemberTest.cs
  37. 33
      csharp/src/Google.Protobuf.Test/WellKnownTypes/DurationTest.cs
  38. BIN
      csharp/src/Google.Protobuf.Test/testprotos.pb
  39. 6
      csharp/src/Google.Protobuf.sln
  40. 10
      csharp/src/Google.Protobuf/Collections/RepeatedField.cs
  41. 7
      csharp/src/Google.Protobuf/Properties/AssemblyInfo.cs
  42. 23
      csharp/src/Google.Protobuf/WellKnownTypes/DurationPartial.cs
  43. 304
      docs/performance.md
  44. 2
      examples/README.md
  45. 11
      kokoro/linux/benchmark/continuous.cfg
  46. 66
      kokoro/linux/benchmark/run.sh
  47. 3
      kokoro/macos/php74/build.sh
  48. 3
      kokoro/macos/php80/build.sh
  49. 5
      kokoro/release/protoc/windows/build.bat
  50. 13
      objectivec/DevTools/compile_testing_protos.sh
  51. 12
      objectivec/ProtocolBuffers_OSX.xcodeproj/project.pbxproj
  52. 12
      objectivec/ProtocolBuffers_iOS.xcodeproj/project.pbxproj
  53. 12
      objectivec/ProtocolBuffers_tvOS.xcodeproj/project.pbxproj
  54. 1
      objectivec/Tests/GPBARCUnittestProtos.m
  55. 0
      objectivec/Tests/GPBCodedOutputStreamTests.m
  56. 2
      objectivec/Tests/GPBUnittestProtos.m
  57. 18
      objectivec/Tests/GPBWellKnownTypesTest.m
  58. 59
      objectivec/Tests/GPBWireFormatTests.m
  59. 6
      objectivec/Tests/any_test.proto
  60. 12
      objectivec/Tests/expected_prefixes.txt
  61. 8
      objectivec/Tests/map_proto2_unittest.proto
  62. 6
      objectivec/Tests/map_unittest.proto
  63. 36
      objectivec/Tests/unittest.proto
  64. 28
      objectivec/Tests/unittest_cycle.proto
  65. 14
      objectivec/Tests/unittest_extension_chain_a.proto
  66. 10
      objectivec/Tests/unittest_extension_chain_b.proto
  67. 8
      objectivec/Tests/unittest_extension_chain_c.proto
  68. 12
      objectivec/Tests/unittest_extension_chain_d.proto
  69. 6
      objectivec/Tests/unittest_extension_chain_e.proto
  70. 8
      objectivec/Tests/unittest_extension_chain_f.proto
  71. 8
      objectivec/Tests/unittest_extension_chain_g.proto
  72. 12
      objectivec/Tests/unittest_import.proto
  73. 6
      objectivec/Tests/unittest_import_public.proto
  74. 60
      objectivec/Tests/unittest_mset.proto
  75. 3
      objectivec/Tests/unittest_objc.proto
  76. 9
      objectivec/Tests/unittest_objc_startup.proto
  77. 3
      objectivec/Tests/unittest_runtime_proto2.proto
  78. 3
      objectivec/Tests/unittest_runtime_proto3.proto
  79. 1
      php/BUILD.bazel
  80. 2
      php/README.md
  81. 3
      php/composer.json
  82. 2
      php/tests/compile_extension.sh
  83. 1
      pkg/BUILD.bazel
  84. 15
      protobuf.bzl
  85. 6
      python/google/protobuf/internal/api_implementation.py
  86. 1
      python/google/protobuf/internal/message_test.py
  87. 2
      python/google/protobuf/internal/python_protobuf.cc
  88. 1
      python/google/protobuf/internal/text_format_test.py
  89. 4
      python/google/protobuf/proto_api.h
  90. 18
      python/google/protobuf/pyext/descriptor.cc
  91. 2
      python/google/protobuf/pyext/descriptor.h
  92. 10
      python/google/protobuf/pyext/descriptor_containers.cc
  93. 12
      python/google/protobuf/pyext/descriptor_database.cc
  94. 2
      python/google/protobuf/pyext/descriptor_database.h
  95. 14
      python/google/protobuf/pyext/descriptor_pool.cc
  96. 2
      python/google/protobuf/pyext/descriptor_pool.h
  97. 26
      python/google/protobuf/pyext/extension_dict.cc
  98. 2
      python/google/protobuf/pyext/extension_dict.h
  99. 8
      python/google/protobuf/pyext/field.cc
  100. 22
      python/google/protobuf/pyext/map_container.cc
  101. Some files were not shown because too many files have changed in this diff Show More

@ -1,5 +1,4 @@
# These are fetched as external repositories.
third_party/abseil-cpp
third_party/benchmark
third_party/googletest
_build/

6
.gitmodules vendored

@ -1,12 +1,8 @@
[submodule "third_party/benchmark"]
path = third_party/benchmark
url = https://github.com/google/benchmark.git
ignore = dirty
[submodule "third_party/googletest"]
path = third_party/googletest
url = https://github.com/google/googletest.git
ignore = dirty
[submodule "third_party/abseil-cpp"]
path = third_party/abseil-cpp
url = https://github.com/abseil/abseil-cpp
url = https://github.com/abseil/abseil-cpp.git
branch = lts_2022_06_23

@ -160,6 +160,7 @@ internal_ruby_proto_library(
cc_binary(
name = "protoc",
copts = COPTS,
linkopts = LINK_OPTS + PROTOC_LINK_OPTS,
visibility = ["//visibility:public"],
deps = ["//src/google/protobuf/compiler:protoc_lib"],

@ -62,6 +62,7 @@ how to install protobuf runtime for that specific language:
| Go | [protocolbuffers/protobuf-go](https://github.com/protocolbuffers/protobuf-go)|
| PHP | [php](php) |
| Dart | [dart-lang/protobuf](https://github.com/dart-lang/protobuf) |
| Javascript | [protocolbuffers/protobuf-javascript](https://github.com/protocolbuffers/protobuf-javascript)|
Quick Start
-----------

@ -16,15 +16,6 @@ http_archive(
],
)
http_archive(
name = "com_github_google_benchmark",
sha256 = "2a778d821997df7d8646c9c59b8edb9a573a6e04c534c01892a40aa524a7b68c",
strip_prefix = "benchmark-bf585a2789e30585b4e3ce6baf11ef2750b54677",
urls = [
"https://github.com/google/benchmark/archive/bf585a2789e30585b4e3ce6baf11ef2750b54677.zip",
],
)
# Bazel platform rules.
http_archive(
name = "platforms",

@ -19,6 +19,7 @@ COPTS = select({
"-DHAVE_ZLIB",
"-Woverloaded-virtual",
"-Wno-sign-compare",
"-Werror",
],
})

@ -33,6 +33,7 @@ set(protobuf_ABSL_USED_TARGETS
absl::algorithm
absl::base
absl::bind_front
absl::bits
absl::cleanup
absl::cord
absl::core_headers
@ -43,6 +44,7 @@ set(protobuf_ABSL_USED_TARGETS
absl::flat_hash_set
absl::function_ref
absl::hash
absl::layout
absl::memory
absl::optional
absl::span

@ -23,8 +23,7 @@ if(${CMAKE_SYSTEM_NAME} STREQUAL "Android")
target_link_libraries(libprotobuf-lite PRIVATE log)
endif()
target_include_directories(libprotobuf-lite PUBLIC ${protobuf_SOURCE_DIR}/src)
target_link_libraries(libprotobuf-lite PRIVATE ${protobuf_ABSL_USED_TARGETS})
target_include_directories(libprotobuf-lite PRIVATE ${ABSL_ROOT_DIR})
target_link_libraries(libprotobuf-lite PUBLIC ${protobuf_ABSL_USED_TARGETS})
if(protobuf_BUILD_SHARED_LIBS)
target_compile_definitions(libprotobuf-lite
PUBLIC PROTOBUF_USE_DLLS

@ -26,8 +26,7 @@ if(${CMAKE_SYSTEM_NAME} STREQUAL "Android")
target_link_libraries(libprotobuf PRIVATE log)
endif()
target_include_directories(libprotobuf PUBLIC ${protobuf_SOURCE_DIR}/src)
target_link_libraries(libprotobuf PRIVATE ${protobuf_ABSL_USED_TARGETS})
target_include_directories(libprotobuf PRIVATE ${ABSL_ROOT_DIR})
target_link_libraries(libprotobuf PUBLIC ${protobuf_ABSL_USED_TARGETS})
if(protobuf_BUILD_SHARED_LIBS)
target_compile_definitions(libprotobuf
PUBLIC PROTOBUF_USE_DLLS

@ -16,8 +16,7 @@ if(protobuf_HAVE_LD_VERSION_SCRIPT)
LINK_DEPENDS ${protobuf_SOURCE_DIR}/src/libprotoc.map)
endif()
target_link_libraries(libprotoc PRIVATE libprotobuf)
target_link_libraries(libprotoc PRIVATE ${protobuf_ABSL_USED_TARGETS})
target_include_directories(libprotoc PRIVATE ${ABSL_ROOT_DIR})
target_link_libraries(libprotoc PUBLIC ${protobuf_ABSL_USED_TARGETS})
if(protobuf_BUILD_SHARED_LIBS)
target_compile_definitions(libprotoc
PUBLIC PROTOBUF_USE_DLLS

@ -40,15 +40,50 @@ tests using similar patterns. You can either use Bazel to run the
or create an executable for a custom test and pass it to
`conformance_test_runner`.
For example, to run the Ruby tests against MRI, you can call:
$ bazel test //ruby:conformance_test
Note: CMake can be used to build the conformance test runner, but not any of
the conformance test executables outside C++. So if you aren't using Bazel
you'll need to create the executable you pass to `conformance_test_runner` via
some alternate build system.
While we plan to model all our supported languages more completely in Bazel,
today some of them are a bit tricky to run. Below is a list of the commands
(and prerequisites) to run each language's conformance tests.
Java:
$ bazel test //java/core:conformance_test //java/lite:conformance_test
Python:
$ bazel test //python:conformance_test
Python C++:
$ bazel test //python:conformance_test_cpp --define=use_fast_cpp_protos=true
C#:
$ `which dotnet || echo "You must have dotnet installed!"
$ `bazel test //csharp:conformance_test \
--action_env=DOTNET_CLI_TELEMETRY_OPTOUT=1 --test_env=DOTNET_CLI_HOME=~ \
--action_env=DOTNET_SYSTEM_GLOBALIZATION_INVARIANT=1
Objective-c (Mac only):
$ `bazel test //objectivec:conformance_test --macos_minimum_os=10.9
Ruby:
$ [[ $(ruby --version) == "ruby"* ]] || echo "Select a C Ruby!"
$ bazel test //ruby:conformance_test --define=ruby_platform=c \
--action_env=PATH --action_env=GEM_PATH --action_env=GEM_HOME
JRuby:
$ [[ $(ruby --version) == "jruby"* ]] || echo "Switch to Java Ruby!"
$ bazel test //ruby:conformance_test --define=ruby_platform=java \
--action_env=PATH --action_env=GEM_PATH --action_env=GEM_HOME
Testing other Protocol Buffer implementations
---------------------------------------------

@ -30,15 +30,15 @@
#include "binary_json_conformance_suite.h"
#include <google/protobuf/text_format.h>
#include <google/protobuf/wire_format_lite.h>
#include <google/protobuf/util/json_util.h>
#include <google/protobuf/util/type_resolver_util.h>
#include "google/protobuf/text_format.h"
#include "google/protobuf/wire_format_lite.h"
#include "google/protobuf/util/json_util.h"
#include "google/protobuf/util/type_resolver_util.h"
#include "absl/status/status.h"
#include "third_party/jsoncpp/json.h"
#include "conformance_test.h"
#include <google/protobuf/test_messages_proto2.pb.h>
#include <google/protobuf/test_messages_proto3.pb.h>
#include "google/protobuf/test_messages_proto2.pb.h"
#include "google/protobuf/test_messages_proto3.pb.h"
namespace proto2_messages = protobuf_test_messages::proto2;
@ -765,7 +765,8 @@ void BinaryAndJsonConformanceSuite::TestValidDataForType(
: cat(tag(field->number(), wire_type), values[i].second);
std::unique_ptr<Message> test_message = NewTestMessage(is_proto3);
test_message->MergeFromString(expected_proto);
string text = test_message->DebugString();
string text;
TextFormat::PrintToString(*test_message, &text);
RunValidProtobufTest(
absl::StrCat("ValidDataScalar", type_name, "[", i, "]"), REQUIRED,
@ -787,7 +788,8 @@ void BinaryAndJsonConformanceSuite::TestValidDataForType(
cat(tag(field->number(), wire_type), values.back().second);
std::unique_ptr<Message> test_message = NewTestMessage(is_proto3);
test_message->MergeFromString(expected_proto);
string text = test_message->DebugString();
string text;
TextFormat::PrintToString(*test_message, &text);
RunValidProtobufTest("RepeatedScalarSelectsLast" + type_name, REQUIRED,
proto, text, is_proto3);
@ -848,7 +850,8 @@ void BinaryAndJsonConformanceSuite::TestValidDataForType(
std::unique_ptr<Message> test_message = NewTestMessage(is_proto3);
test_message->MergeFromString(default_proto_packed_expected);
string text = test_message->DebugString();
string text;
TextFormat::PrintToString(*test_message, &text);
// Ensures both packed and unpacked data can be parsed.
RunValidProtobufTest(
@ -897,7 +900,8 @@ void BinaryAndJsonConformanceSuite::TestValidDataForType(
}
std::unique_ptr<Message> test_message = NewTestMessage(is_proto3);
test_message->MergeFromString(expected_proto);
string text = test_message->DebugString();
string text;
TextFormat::PrintToString(*test_message, &text);
RunValidProtobufTest(absl::StrCat("ValidDataRepeated", type_name),
REQUIRED, proto, text, is_proto3);
@ -974,7 +978,8 @@ void BinaryAndJsonConformanceSuite::TestValidDataForMapType(
delim(cat(key1_data, value1_data)));
std::unique_ptr<Message> test_message = NewTestMessage(is_proto3);
test_message->MergeFromString(proto);
string text = test_message->DebugString();
string text;
TextFormat::PrintToString(*test_message, &text);
RunValidProtobufTest(absl::StrCat("ValidDataMap", key_type_name,
value_type_name, ".Default"),
REQUIRED, proto, text, is_proto3);
@ -987,7 +992,8 @@ void BinaryAndJsonConformanceSuite::TestValidDataForMapType(
delim(""));
std::unique_ptr<Message> test_message = NewTestMessage(is_proto3);
test_message->MergeFromString(proto);
string text = test_message->DebugString();
string text;
TextFormat::PrintToString(*test_message, &text);
RunValidProtobufTest(absl::StrCat("ValidDataMap", key_type_name,
value_type_name, ".MissingDefault"),
REQUIRED, proto, text, is_proto3);
@ -1000,7 +1006,8 @@ void BinaryAndJsonConformanceSuite::TestValidDataForMapType(
delim(cat(key2_data, value2_data)));
std::unique_ptr<Message> test_message = NewTestMessage(is_proto3);
test_message->MergeFromString(proto);
string text = test_message->DebugString();
string text;
TextFormat::PrintToString(*test_message, &text);
RunValidProtobufTest(absl::StrCat("ValidDataMap", key_type_name,
value_type_name, ".NonDefault"),
REQUIRED, proto, text, is_proto3);
@ -1013,7 +1020,8 @@ void BinaryAndJsonConformanceSuite::TestValidDataForMapType(
delim(cat(value2_data, key2_data)));
std::unique_ptr<Message> test_message = NewTestMessage(is_proto3);
test_message->MergeFromString(proto);
string text = test_message->DebugString();
string text;
TextFormat::PrintToString(*test_message, &text);
RunValidProtobufTest(absl::StrCat("ValidDataMap", key_type_name,
value_type_name, ".Unordered"),
REQUIRED, proto, text, is_proto3);
@ -1030,7 +1038,8 @@ void BinaryAndJsonConformanceSuite::TestValidDataForMapType(
string proto = cat(proto1, proto2);
std::unique_ptr<Message> test_message = NewTestMessage(is_proto3);
test_message->MergeFromString(proto2);
string text = test_message->DebugString();
string text;
TextFormat::PrintToString(*test_message, &text);
RunValidProtobufTest(absl::StrCat("ValidDataMap", key_type_name,
value_type_name, ".DuplicateKey"),
REQUIRED, proto, text, is_proto3);
@ -1043,7 +1052,8 @@ void BinaryAndJsonConformanceSuite::TestValidDataForMapType(
delim(cat(key1_data, key2_data, value2_data)));
std::unique_ptr<Message> test_message = NewTestMessage(is_proto3);
test_message->MergeFromString(proto);
string text = test_message->DebugString();
string text;
TextFormat::PrintToString(*test_message, &text);
RunValidProtobufTest(
absl::StrCat("ValidDataMap", key_type_name, value_type_name,
".DuplicateKeyInMapEntry"),
@ -1057,7 +1067,8 @@ void BinaryAndJsonConformanceSuite::TestValidDataForMapType(
delim(cat(key2_data, value1_data, value2_data)));
std::unique_ptr<Message> test_message = NewTestMessage(is_proto3);
test_message->MergeFromString(proto);
string text = test_message->DebugString();
string text;
TextFormat::PrintToString(*test_message, &text);
RunValidProtobufTest(
absl::StrCat("ValidDataMap", key_type_name, value_type_name,
".DuplicateValueInMapEntry"),
@ -1097,7 +1108,8 @@ void BinaryAndJsonConformanceSuite::TestOverwriteMessageValueMap() {
string proto = cat(proto1, proto2);
std::unique_ptr<Message> test_message = NewTestMessage(is_proto3);
test_message->MergeFromString(proto2);
string text = test_message->DebugString();
string text;
TextFormat::PrintToString(*test_message, &text);
RunValidProtobufTest("ValidDataMap.STRING.MESSAGE.MergeValue", REQUIRED,
proto, text, is_proto3);
}
@ -1122,7 +1134,8 @@ void BinaryAndJsonConformanceSuite::TestValidDataForOneofType(
const string proto = default_value;
std::unique_ptr<Message> test_message = NewTestMessage(is_proto3);
test_message->MergeFromString(proto);
string text = test_message->DebugString();
string text;
TextFormat::PrintToString(*test_message, &text);
RunValidProtobufTest(
absl::StrCat("ValidDataOneof", type_name, ".DefaultValue"), REQUIRED,
@ -1137,7 +1150,8 @@ void BinaryAndJsonConformanceSuite::TestValidDataForOneofType(
const string proto = non_default_value;
std::unique_ptr<Message> test_message = NewTestMessage(is_proto3);
test_message->MergeFromString(proto);
string text = test_message->DebugString();
string text;
TextFormat::PrintToString(*test_message, &text);
RunValidProtobufTest(
absl::StrCat("ValidDataOneof", type_name, ".NonDefaultValue"),
@ -1153,7 +1167,8 @@ void BinaryAndJsonConformanceSuite::TestValidDataForOneofType(
const string expected_proto = non_default_value;
std::unique_ptr<Message> test_message = NewTestMessage(is_proto3);
test_message->MergeFromString(expected_proto);
string text = test_message->DebugString();
string text;
TextFormat::PrintToString(*test_message, &text);
RunValidProtobufTest(absl::StrCat("ValidDataOneof", type_name,
".MultipleValuesForSameField"),
@ -1179,7 +1194,8 @@ void BinaryAndJsonConformanceSuite::TestValidDataForOneofType(
const string expected_proto = non_default_value;
std::unique_ptr<Message> test_message = NewTestMessage(is_proto3);
test_message->MergeFromString(expected_proto);
string text = test_message->DebugString();
string text;
TextFormat::PrintToString(*test_message, &text);
RunValidProtobufTest(absl::StrCat("ValidDataOneof", type_name,
".MultipleValuesForDifferentField"),
@ -1224,7 +1240,8 @@ void BinaryAndJsonConformanceSuite::TestMergeOneofMessage() {
std::unique_ptr<Message> test_message = NewTestMessage(is_proto3);
test_message->MergeFromString(expected_proto);
string text = test_message->DebugString();
string text;
TextFormat::PrintToString(*test_message, &text);
RunValidProtobufTest("ValidDataOneof.MESSAGE.Merge", REQUIRED, proto, text,
is_proto3);
RunValidBinaryProtobufTest("ValidDataOneofBinary.MESSAGE.Merge",

@ -36,24 +36,24 @@
#include <string>
#include <utility>
#include <google/protobuf/stubs/logging.h>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/message.h>
#include <google/protobuf/text_format.h>
#include <google/protobuf/util/json_util.h>
#include <google/protobuf/util/type_resolver_util.h>
#include "google/protobuf/stubs/logging.h"
#include "google/protobuf/stubs/common.h"
#include "google/protobuf/message.h"
#include "google/protobuf/text_format.h"
#include "google/protobuf/util/json_util.h"
#include "google/protobuf/util/type_resolver_util.h"
#include "absl/status/status.h"
#include "absl/status/statusor.h"
#include "conformance/conformance.pb.h"
#include "conformance/conformance.pb.h"
#include <google/protobuf/test_messages_proto2.pb.h>
#include <google/protobuf/test_messages_proto3.pb.h>
#include <google/protobuf/test_messages_proto3.pb.h>
#include <google/protobuf/util/type_resolver.h>
#include <google/protobuf/stubs/status_macros.h>
#include "google/protobuf/test_messages_proto2.pb.h"
#include "google/protobuf/test_messages_proto3.pb.h"
#include "google/protobuf/test_messages_proto3.pb.h"
#include "google/protobuf/util/type_resolver.h"
#include "google/protobuf/stubs/status_macros.h"
// Must be included last.
#include <google/protobuf/port_def.inc>
#include "google/protobuf/port_def.inc"
namespace google {
namespace protobuf {
@ -87,7 +87,7 @@ absl::Status ReadFd(int fd, char* buf, size_t len) {
}
absl::Status WriteFd(int fd, const void* buf, size_t len) {
if (write(fd, buf, len) != len) {
if (static_cast<size_t>(write(fd, buf, len)) != len) {
return absl::ErrnoToStatus(errno, "error reading to test runner");
}
return absl::OkStatus();

@ -36,12 +36,12 @@
#include <set>
#include <string>
#include <google/protobuf/stubs/stringprintf.h>
#include <google/protobuf/message.h>
#include <google/protobuf/text_format.h>
#include <google/protobuf/util/field_comparator.h>
#include <google/protobuf/util/json_util.h>
#include <google/protobuf/util/message_differencer.h>
#include "google/protobuf/stubs/stringprintf.h"
#include "google/protobuf/message.h"
#include "google/protobuf/text_format.h"
#include "google/protobuf/util/field_comparator.h"
#include "google/protobuf/util/json_util.h"
#include "google/protobuf/util/message_differencer.h"
#include "conformance/conformance.pb.h"
using conformance::ConformanceRequest;

@ -42,9 +42,9 @@
#include <string>
#include <vector>
#include <google/protobuf/descriptor.h>
#include <google/protobuf/wire_format_lite.h>
#include <google/protobuf/util/type_resolver.h>
#include "google/protobuf/descriptor.h"
#include "google/protobuf/wire_format_lite.h"
#include "google/protobuf/util/type_resolver.h"
#include "conformance/conformance.pb.h"
namespace conformance {

@ -62,7 +62,7 @@
#include <fstream>
#include <vector>
#include <google/protobuf/stubs/stringprintf.h>
#include "google/protobuf/stubs/stringprintf.h"
#include "conformance/conformance.pb.h"
#include "conformance_test.h"

@ -30,11 +30,11 @@
#include "text_format_conformance_suite.h"
#include <google/protobuf/any.pb.h>
#include <google/protobuf/text_format.h>
#include "google/protobuf/any.pb.h"
#include "google/protobuf/text_format.h"
#include "conformance_test.h"
#include <google/protobuf/test_messages_proto2.pb.h>
#include <google/protobuf/test_messages_proto3.pb.h>
#include "google/protobuf/test_messages_proto2.pb.h"
#include "google/protobuf/test_messages_proto3.pb.h"
namespace proto2_messages = protobuf_test_messages::proto2;

@ -33,7 +33,6 @@ filegroup(
"src/*/obj/**/*"
]) + [
"src/Directory.Build.props",
"src/Google.Protobuf.Benchmarks/wrapper_benchmark_messages.proto",
"src/Google.Protobuf.Test/testprotos.pb",
"src/Google.Protobuf.sln",
],
@ -67,7 +66,6 @@ inline_sh_test(
":srcs",
"src/Google.Protobuf.sln",
"//csharp/src/Google.Protobuf.Conformance:srcs",
"//benchmarks/datasets:proto3_datasets"
],
cmd = """
pushd `dirname $(location src/Google.Protobuf.sln)`/..

@ -76,14 +76,3 @@ $PROTOC -Isrc -Icsharp/protos \
# AddressBook sample protos
$PROTOC -Iexamples -Isrc --csharp_out=csharp/src/AddressBook \
examples/addressbook.proto
# Benchmark protos
$PROTOC -Ibenchmarks \
benchmarks/datasets/google_message1/proto3/*.proto \
benchmarks/benchmarks.proto \
--csharp_out=csharp/src/Google.Protobuf.Benchmarks
# C# only benchmark protos
$PROTOC -Isrc -Icsharp/src/Google.Protobuf.Benchmarks \
csharp/src/Google.Protobuf.Benchmarks/*.proto \
--csharp_out=csharp/src/Google.Protobuf.Benchmarks

@ -59,10 +59,12 @@ message NegativeEnumMessage {
// Decorate fields with [deprecated=true] as [System.Obsolete]
message DeprecatedChild {
option deprecated = true;
}
enum DeprecatedEnum {
DEPRECATED_ZERO = 0;
option deprecated = true;
DEPRECATED_ZERO = 0 [deprecated = true];
one = 1;
}

@ -1,87 +0,0 @@
#region Copyright notice and license
// Protocol Buffers - Google's data interchange format
// Copyright 2019 Google Inc. All rights reserved.
// https://github.com/protocolbuffers/protobuf
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#endregion
using Benchmarks;
using Google.Protobuf.Reflection;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
namespace Google.Protobuf.Benchmarks
{
/// <summary>
/// The configuration for a single serialization test, loaded from a dataset.
/// </summary>
public class BenchmarkDatasetConfig
{
private static readonly Dictionary<string, MessageParser> parsersByMessageName =
typeof(GoogleMessageBenchmark).Assembly.GetTypes()
.Where(t => typeof(IMessage).IsAssignableFrom(t))
.ToDictionary(
t => ((MessageDescriptor) t.GetProperty("Descriptor", BindingFlags.Static | BindingFlags.Public).GetValue(null)).FullName,
t => ((MessageParser) t.GetProperty("Parser", BindingFlags.Static | BindingFlags.Public).GetValue(null)));
public MessageParser Parser { get; }
public List<byte[]> Payloads { get; }
public string Name { get; }
public BenchmarkDatasetConfig(string resource, string shortName = null)
{
var data = LoadData(resource);
var dataset = BenchmarkDataset.Parser.ParseFrom(data);
if (!parsersByMessageName.TryGetValue(dataset.MessageName, out var parser))
{
throw new ArgumentException($"No parser for message {dataset.MessageName} in this assembly");
}
Parser = parser;
Payloads = new List<byte[]>(dataset.Payload.Select(p => p.ToByteArray()));
Name = shortName ?? dataset.Name;
}
private static byte[] LoadData(string resource)
{
using var stream = typeof(GoogleMessageBenchmark).Assembly.GetManifestResourceStream($"Google.Protobuf.Benchmarks.{resource}");
if (stream == null)
{
throw new ArgumentException($"Unable to load embedded resource {resource}");
}
var copy = new MemoryStream();
stream.CopyTo(copy);
return copy.ToArray();
}
public override string ToString() => Name;
}
}

@ -1,325 +0,0 @@
// <auto-generated>
// Generated by the protocol buffer compiler. DO NOT EDIT!
// source: benchmarks.proto
// </auto-generated>
#pragma warning disable 1591, 0612, 3021, 8981
#region Designer generated code
using pb = global::Google.Protobuf;
using pbc = global::Google.Protobuf.Collections;
using pbr = global::Google.Protobuf.Reflection;
using scg = global::System.Collections.Generic;
namespace Benchmarks {
/// <summary>Holder for reflection information generated from benchmarks.proto</summary>
public static partial class BenchmarksReflection {
#region Descriptor
/// <summary>File descriptor for benchmarks.proto</summary>
public static pbr::FileDescriptor Descriptor {
get { return descriptor; }
}
private static pbr::FileDescriptor descriptor;
static BenchmarksReflection() {
byte[] descriptorData = global::System.Convert.FromBase64String(
string.Concat(
"ChBiZW5jaG1hcmtzLnByb3RvEgpiZW5jaG1hcmtzIkcKEEJlbmNobWFya0Rh",
"dGFzZXQSDAoEbmFtZRgBIAEoCRIUCgxtZXNzYWdlX25hbWUYAiABKAkSDwoH",
"cGF5bG9hZBgDIAMoDEIgCh5jb20uZ29vZ2xlLnByb3RvYnVmLmJlbmNobWFy",
"a3NiBnByb3RvMw=="));
descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
new pbr::FileDescriptor[] { },
new pbr::GeneratedClrTypeInfo(null, null, new pbr::GeneratedClrTypeInfo[] {
new pbr::GeneratedClrTypeInfo(typeof(global::Benchmarks.BenchmarkDataset), global::Benchmarks.BenchmarkDataset.Parser, new[]{ "Name", "MessageName", "Payload" }, null, null, null, null)
}));
}
#endregion
}
#region Messages
public sealed partial class BenchmarkDataset : pb::IMessage<BenchmarkDataset>
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
, pb::IBufferMessage
#endif
{
private static readonly pb::MessageParser<BenchmarkDataset> _parser = new pb::MessageParser<BenchmarkDataset>(() => new BenchmarkDataset());
private pb::UnknownFieldSet _unknownFields;
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
public static pb::MessageParser<BenchmarkDataset> Parser { get { return _parser; } }
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
public static pbr::MessageDescriptor Descriptor {
get { return global::Benchmarks.BenchmarksReflection.Descriptor.MessageTypes[0]; }
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
pbr::MessageDescriptor pb::IMessage.Descriptor {
get { return Descriptor; }
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
public BenchmarkDataset() {
OnConstruction();
}
partial void OnConstruction();
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
public BenchmarkDataset(BenchmarkDataset other) : this() {
name_ = other.name_;
messageName_ = other.messageName_;
payload_ = other.payload_.Clone();
_unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
public BenchmarkDataset Clone() {
return new BenchmarkDataset(this);
}
/// <summary>Field number for the "name" field.</summary>
public const int NameFieldNumber = 1;
private string name_ = "";
/// <summary>
/// Name of the benchmark dataset. This should be unique across all datasets.
/// Should only contain word characters: [a-zA-Z0-9_]
/// </summary>
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
public string Name {
get { return name_; }
set {
name_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
}
}
/// <summary>Field number for the "message_name" field.</summary>
public const int MessageNameFieldNumber = 2;
private string messageName_ = "";
/// <summary>
/// Fully-qualified name of the protobuf message for this dataset.
/// It will be one of the messages defined benchmark_messages_proto2.proto
/// or benchmark_messages_proto3.proto.
///
/// Implementations that do not support reflection can implement this with
/// an explicit "if/else" chain that lists every known message defined
/// in those files.
/// </summary>
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
public string MessageName {
get { return messageName_; }
set {
messageName_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
}
}
/// <summary>Field number for the "payload" field.</summary>
public const int PayloadFieldNumber = 3;
private static readonly pb::FieldCodec<pb::ByteString> _repeated_payload_codec
= pb::FieldCodec.ForBytes(26);
private readonly pbc::RepeatedField<pb::ByteString> payload_ = new pbc::RepeatedField<pb::ByteString>();
/// <summary>
/// The payload(s) for this dataset. They should be parsed or serialized
/// in sequence, in a loop, ie.
///
/// while (!benchmarkDone) { // Benchmark runner decides when to exit.
/// for (i = 0; i &lt; benchmark.payload.length; i++) {
/// parse(benchmark.payload[i])
/// }
/// }
///
/// This is intended to let datasets include a variety of data to provide
/// potentially more realistic results than just parsing the same message
/// over and over. A single message parsed repeatedly could yield unusually
/// good branch prediction performance.
/// </summary>
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
public pbc::RepeatedField<pb::ByteString> Payload {
get { return payload_; }
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
public override bool Equals(object other) {
return Equals(other as BenchmarkDataset);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
public bool Equals(BenchmarkDataset other) {
if (ReferenceEquals(other, null)) {
return false;
}
if (ReferenceEquals(other, this)) {
return true;
}
if (Name != other.Name) return false;
if (MessageName != other.MessageName) return false;
if(!payload_.Equals(other.payload_)) return false;
return Equals(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
public override int GetHashCode() {
int hash = 1;
if (Name.Length != 0) hash ^= Name.GetHashCode();
if (MessageName.Length != 0) hash ^= MessageName.GetHashCode();
hash ^= payload_.GetHashCode();
if (_unknownFields != null) {
hash ^= _unknownFields.GetHashCode();
}
return hash;
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
public override string ToString() {
return pb::JsonFormatter.ToDiagnosticString(this);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
public void WriteTo(pb::CodedOutputStream output) {
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
output.WriteRawMessage(this);
#else
if (Name.Length != 0) {
output.WriteRawTag(10);
output.WriteString(Name);
}
if (MessageName.Length != 0) {
output.WriteRawTag(18);
output.WriteString(MessageName);
}
payload_.WriteTo(output, _repeated_payload_codec);
if (_unknownFields != null) {
_unknownFields.WriteTo(output);
}
#endif
}
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) {
if (Name.Length != 0) {
output.WriteRawTag(10);
output.WriteString(Name);
}
if (MessageName.Length != 0) {
output.WriteRawTag(18);
output.WriteString(MessageName);
}
payload_.WriteTo(ref output, _repeated_payload_codec);
if (_unknownFields != null) {
_unknownFields.WriteTo(ref output);
}
}
#endif
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
public int CalculateSize() {
int size = 0;
if (Name.Length != 0) {
size += 1 + pb::CodedOutputStream.ComputeStringSize(Name);
}
if (MessageName.Length != 0) {
size += 1 + pb::CodedOutputStream.ComputeStringSize(MessageName);
}
size += payload_.CalculateSize(_repeated_payload_codec);
if (_unknownFields != null) {
size += _unknownFields.CalculateSize();
}
return size;
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
public void MergeFrom(BenchmarkDataset other) {
if (other == null) {
return;
}
if (other.Name.Length != 0) {
Name = other.Name;
}
if (other.MessageName.Length != 0) {
MessageName = other.MessageName;
}
payload_.Add(other.payload_);
_unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
public void MergeFrom(pb::CodedInputStream input) {
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
input.ReadRawMessage(this);
#else
uint tag;
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
_unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
break;
case 10: {
Name = input.ReadString();
break;
}
case 18: {
MessageName = input.ReadString();
break;
}
case 26: {
payload_.AddEntriesFrom(input, _repeated_payload_codec);
break;
}
}
}
#endif
}
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) {
uint tag;
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
_unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input);
break;
case 10: {
Name = input.ReadString();
break;
}
case 18: {
MessageName = input.ReadString();
break;
}
case 26: {
payload_.AddEntriesFrom(ref input, _repeated_payload_codec);
break;
}
}
}
}
#endif
}
#endregion
}
#endregion Designer generated code

@ -1,72 +0,0 @@
#region Copyright notice and license
// Protocol Buffers - Google's data interchange format
// Copyright 2019 Google Inc. All rights reserved.
// https://github.com/protocolbuffers/protobuf
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#endregion
using BenchmarkDotNet.Attributes;
namespace Google.Protobuf.Benchmarks
{
/// <summary>
/// Benchmarks using ByteString.
/// </summary>
[MemoryDiagnoser]
public class ByteStringBenchmark
{
private const int Zero = 0;
private const int Kilobyte = 1024;
private const int _128Kilobytes = 1024 * 128;
private const int Megabyte = 1024 * 1024;
private const int _10Megabytes = 1024 * 1024 * 10;
byte[] byteBuffer;
[GlobalSetup]
public void GlobalSetup()
{
byteBuffer = new byte[PayloadSize];
}
[Params(Zero, Kilobyte, _128Kilobytes, Megabyte, _10Megabytes)]
public int PayloadSize { get; set; }
[Benchmark]
public ByteString CopyFrom()
{
return ByteString.CopyFrom(byteBuffer);
}
[Benchmark]
public ByteString UnsafeWrap()
{
return UnsafeByteOperations.UnsafeWrap(byteBuffer);
}
}
}

@ -1,26 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework>
<AssemblyOriginatorKeyFile>../../keys/Google.Protobuf.snk</AssemblyOriginatorKeyFile>
<SignAssembly>true</SignAssembly>
<IsPackable>False</IsPackable>
<DebugType>pdbonly</DebugType>
<DebugSymbols>true</DebugSymbols>
</PropertyGroup>
<ItemGroup>
<Compile Include="..\Google.Protobuf.Test\ReadOnlySequenceFactory.cs" Link="ReadOnlySequenceFactory.cs" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="BenchmarkDotNet" Version="0.13.1" />
<ProjectReference Include="..\Google.Protobuf\Google.Protobuf.csproj" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="..\..\..\benchmarks\datasets\google_message1\proto3\dataset.google_message1_proto3.pb" />
</ItemGroup>
</Project>

@ -1,124 +0,0 @@
#region Copyright notice and license
// Protocol Buffers - Google's data interchange format
// Copyright 2019 Google Inc. All rights reserved.
// https://github.com/protocolbuffers/protobuf
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#endregion
using BenchmarkDotNet.Attributes;
using System.Collections.Generic;
using System.IO;
using System.Linq;
namespace Google.Protobuf.Benchmarks
{
/// <summary>
/// Benchmark for serializing and deserializing of standard datasets that are also
/// measured by benchmarks in other languages.
/// Over time we may wish to test the various different approaches to serialization and deserialization separately.
/// See https://github.com/protocolbuffers/protobuf/blob/main/benchmarks/README.md
/// See https://github.com/protocolbuffers/protobuf/blob/main/docs/performance.md
/// </summary>
[MemoryDiagnoser]
public class GoogleMessageBenchmark
{
/// <summary>
/// All the datasets to be tested. Add more datasets to the array as they're available.
/// (When C# supports proto2, this will increase significantly.)
/// </summary>
public static BenchmarkDatasetConfig[] DatasetConfigurations => new[]
{
// short name is specified to make results table more readable
new BenchmarkDatasetConfig("dataset.google_message1_proto3.pb", "goog_msg1_proto3")
};
[ParamsSource(nameof(DatasetConfigurations))]
public BenchmarkDatasetConfig Dataset { get; set; }
private MessageParser parser;
/// <summary>
/// Each data set can contain multiple messages in a single file.
/// Each "write" operation should write each message in turn, and each "parse"
/// operation should parse each message in turn.
/// </summary>
private List<SubTest> subTests;
[GlobalSetup]
public void GlobalSetup()
{
parser = Dataset.Parser;
subTests = Dataset.Payloads.Select(p => new SubTest(p, parser.ParseFrom(p))).ToList();
}
[Benchmark]
public void WriteToStream() => subTests.ForEach(item => item.WriteToStream());
[Benchmark]
public void ToByteArray() => subTests.ForEach(item => item.ToByteArray());
[Benchmark]
public void ParseFromByteArray() => subTests.ForEach(item => item.ParseFromByteArray(parser));
[Benchmark]
public void ParseFromStream() => subTests.ForEach(item => item.ParseFromStream(parser));
private class SubTest
{
private readonly Stream destinationStream;
private readonly Stream sourceStream;
private readonly byte[] data;
private readonly IMessage message;
public SubTest(byte[] data, IMessage message)
{
destinationStream = new MemoryStream(data.Length);
sourceStream = new MemoryStream(data);
this.data = data;
this.message = message;
}
public void Reset() => destinationStream.Position = 0;
public void WriteToStream()
{
destinationStream.Position = 0;
message.WriteTo(destinationStream);
}
public void ToByteArray() => message.ToByteArray();
public void ParseFromByteArray(MessageParser parser) => parser.ParseFrom(data);
public void ParseFromStream(MessageParser parser)
{
sourceStream.Position = 0;
parser.ParseFrom(sourceStream);
}
}
}
}

@ -1,258 +0,0 @@
#region Copyright notice and license
// Protocol Buffers - Google's data interchange format
// Copyright 2019 Google Inc. All rights reserved.
// https://github.com/protocolbuffers/protobuf
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#endregion
using BenchmarkDotNet.Attributes;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Buffers;
using Google.Protobuf.WellKnownTypes;
using Benchmarks.Proto3;
namespace Google.Protobuf.Benchmarks
{
/// <summary>
/// Benchmark that tests parsing performance for various messages.
/// </summary>
[MemoryDiagnoser]
public class ParseMessagesBenchmark
{
const int MaxMessages = 100;
private readonly SubTest manyWrapperFieldsTest = new(CreateManyWrapperFieldsMessage(), ManyWrapperFieldsMessage.Parser, () => new ManyWrapperFieldsMessage(), MaxMessages);
private readonly SubTest manyPrimitiveFieldsTest = new(CreateManyPrimitiveFieldsMessage(), ManyPrimitiveFieldsMessage.Parser, () => new ManyPrimitiveFieldsMessage(), MaxMessages);
private readonly SubTest repeatedFieldTest = new(CreateRepeatedFieldMessage(), GoogleMessage1.Parser, () => new GoogleMessage1(), MaxMessages);
private readonly SubTest emptyMessageTest = new(new Empty(), Empty.Parser, () => new Empty(), MaxMessages);
public IEnumerable<int> MessageCountValues => new[] { 10, 100 };
[GlobalSetup]
public void GlobalSetup()
{
}
[Benchmark]
public IMessage ManyWrapperFieldsMessage_ParseFromByteArray()
{
return manyWrapperFieldsTest.ParseFromByteArray();
}
[Benchmark]
public IMessage ManyWrapperFieldsMessage_ParseFromReadOnlySequence()
{
return manyWrapperFieldsTest.ParseFromReadOnlySequence();
}
[Benchmark]
public IMessage ManyPrimitiveFieldsMessage_ParseFromByteArray()
{
return manyPrimitiveFieldsTest.ParseFromByteArray();
}
[Benchmark]
public IMessage ManyPrimitiveFieldsMessage_ParseFromReadOnlySequence()
{
return manyPrimitiveFieldsTest.ParseFromReadOnlySequence();
}
[Benchmark]
public IMessage RepeatedFieldMessage_ParseFromByteArray()
{
return repeatedFieldTest.ParseFromByteArray();
}
[Benchmark]
public IMessage RepeatedFieldMessage_ParseFromReadOnlySequence()
{
return repeatedFieldTest.ParseFromReadOnlySequence();
}
[Benchmark]
public IMessage EmptyMessage_ParseFromByteArray()
{
return emptyMessageTest.ParseFromByteArray();
}
[Benchmark]
public IMessage EmptyMessage_ParseFromReadOnlySequence()
{
return emptyMessageTest.ParseFromReadOnlySequence();
}
[Benchmark]
[ArgumentsSource(nameof(MessageCountValues))]
public void ManyWrapperFieldsMessage_ParseDelimitedMessagesFromByteArray(int messageCount)
{
manyWrapperFieldsTest.ParseDelimitedMessagesFromByteArray(messageCount);
}
[Benchmark]
[ArgumentsSource(nameof(MessageCountValues))]
public void ManyWrapperFieldsMessage_ParseDelimitedMessagesFromReadOnlySequence(int messageCount)
{
manyWrapperFieldsTest.ParseDelimitedMessagesFromReadOnlySequence(messageCount);
}
[Benchmark]
[ArgumentsSource(nameof(MessageCountValues))]
public void ManyPrimitiveFieldsMessage_ParseDelimitedMessagesFromByteArray(int messageCount)
{
manyPrimitiveFieldsTest.ParseDelimitedMessagesFromByteArray(messageCount);
}
[Benchmark]
[ArgumentsSource(nameof(MessageCountValues))]
public void ManyPrimitiveFieldsMessage_ParseDelimitedMessagesFromReadOnlySequence(int messageCount)
{
manyPrimitiveFieldsTest.ParseDelimitedMessagesFromReadOnlySequence(messageCount);
}
[Benchmark]
[ArgumentsSource(nameof(MessageCountValues))]
public void RepeatedFieldMessage_ParseDelimitedMessagesFromByteArray(int messageCount)
{
repeatedFieldTest.ParseDelimitedMessagesFromByteArray(messageCount);
}
[Benchmark]
[ArgumentsSource(nameof(MessageCountValues))]
public void RepeatedFieldMessage_ParseDelimitedMessagesFromReadOnlySequence(int messageCount)
{
repeatedFieldTest.ParseDelimitedMessagesFromReadOnlySequence(messageCount);
}
public static ManyWrapperFieldsMessage CreateManyWrapperFieldsMessage()
{
// Example data match data of an internal benchmarks
return new ManyWrapperFieldsMessage()
{
Int64Field19 = 123,
Int64Field37 = 1000032,
Int64Field26 = 3453524500,
DoubleField79 = 1.2,
DoubleField25 = 234,
DoubleField9 = 123.3,
DoubleField28 = 23,
DoubleField7 = 234,
DoubleField50 = 2.45
};
}
public static ManyPrimitiveFieldsMessage CreateManyPrimitiveFieldsMessage()
{
// Example data match data of an internal benchmarks
return new ManyPrimitiveFieldsMessage()
{
Int64Field19 = 123,
Int64Field37 = 1000032,
Int64Field26 = 3453524500,
DoubleField79 = 1.2,
DoubleField25 = 234,
DoubleField9 = 123.3,
DoubleField28 = 23,
DoubleField7 = 234,
DoubleField50 = 2.45
};
}
public static GoogleMessage1 CreateRepeatedFieldMessage()
{
// Message with a repeated fixed length item collection
var message = new GoogleMessage1();
for (ulong i = 0; i < 1000; i++)
{
message.Field5.Add(i);
}
return message;
}
private class SubTest
{
private readonly IMessage message;
private readonly MessageParser parser;
private readonly Func<IMessage> factory;
private readonly byte[] data;
private readonly byte[] multipleMessagesData;
private readonly ReadOnlySequence<byte> dataSequence;
private readonly ReadOnlySequence<byte> multipleMessagesDataSequence;
public SubTest(IMessage message, MessageParser parser, Func<IMessage> factory, int maxMessageCount)
{
this.message = message;
this.parser = parser;
this.factory = factory;
this.data = message.ToByteArray();
this.multipleMessagesData = CreateBufferWithMultipleMessages(message, maxMessageCount);
this.dataSequence = new ReadOnlySequence<byte>(this.data);
this.multipleMessagesDataSequence = new ReadOnlySequence<byte>(this.multipleMessagesData);
}
public IMessage ParseFromByteArray() => parser.ParseFrom(data);
public IMessage ParseFromReadOnlySequence() => parser.ParseFrom(dataSequence);
public void ParseDelimitedMessagesFromByteArray(int messageCount)
{
var input = new CodedInputStream(multipleMessagesData);
for (int i = 0; i < messageCount; i++)
{
var msg = factory();
input.ReadMessage(msg);
}
}
public void ParseDelimitedMessagesFromReadOnlySequence(int messageCount)
{
ParseContext.Initialize(multipleMessagesDataSequence, out ParseContext ctx);
for (int i = 0; i < messageCount; i++)
{
var msg = factory();
ctx.ReadMessage(msg);
}
}
private static byte[] CreateBufferWithMultipleMessages(IMessage msg, int msgCount)
{
var ms = new MemoryStream();
var cos = new CodedOutputStream(ms);
for (int i = 0; i < msgCount; i++)
{
cos.WriteMessage(msg);
}
cos.Flush();
return ms.ToArray();
}
}
}
}

@ -1,536 +0,0 @@
#region Copyright notice and license
// Protocol Buffers - Google's data interchange format
// Copyright 2019 Google Inc. All rights reserved.
// https://github.com/protocolbuffers/protobuf
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#endregion
using BenchmarkDotNet.Attributes;
using System;
using System.Buffers.Binary;
using System.Collections.Generic;
using System.IO;
using System.Buffers;
namespace Google.Protobuf.Benchmarks
{
/// <summary>
/// Benchmarks throughput when parsing raw primitives.
/// </summary>
[MemoryDiagnoser]
public class ParseRawPrimitivesBenchmark
{
// key is the encodedSize of varint values
Dictionary<int, byte[]> varintInputBuffers;
byte[] doubleInputBuffer;
byte[] floatInputBuffer;
byte[] fixedIntInputBuffer;
// key is the encodedSize of string values
Dictionary<int, byte[]> stringInputBuffers;
Dictionary<int, ReadOnlySequence<byte>> stringInputBuffersSegmented;
Random random = new Random(417384220); // random but deterministic seed
public IEnumerable<int> StringEncodedSizes => new[] { 1, 4, 10, 105, 10080 };
public IEnumerable<int> StringSegmentedEncodedSizes => new[] { 105, 10080 };
[GlobalSetup]
public void GlobalSetup()
{
// add some extra values that we won't read just to make sure we are far enough from the end of the buffer
// which allows the parser fastpath to always kick in.
const int paddingValueCount = 100;
varintInputBuffers = new Dictionary<int, byte[]>();
for (int encodedSize = 1; encodedSize <= 10; encodedSize++)
{
byte[] buffer = CreateBufferWithRandomVarints(random, BytesToParse / encodedSize, encodedSize, paddingValueCount);
varintInputBuffers.Add(encodedSize, buffer);
}
doubleInputBuffer = CreateBufferWithRandomDoubles(random, BytesToParse / sizeof(double), paddingValueCount);
floatInputBuffer = CreateBufferWithRandomFloats(random, BytesToParse / sizeof(float), paddingValueCount);
fixedIntInputBuffer = CreateBufferWithRandomData(random, BytesToParse / sizeof(long), sizeof(long), paddingValueCount);
stringInputBuffers = new Dictionary<int, byte[]>();
foreach (var encodedSize in StringEncodedSizes)
{
byte[] buffer = CreateBufferWithStrings(BytesToParse / encodedSize, encodedSize, encodedSize < 10 ? 10 : 1 );
stringInputBuffers.Add(encodedSize, buffer);
}
stringInputBuffersSegmented = new Dictionary<int, ReadOnlySequence<byte>>();
foreach (var encodedSize in StringSegmentedEncodedSizes)
{
byte[] buffer = CreateBufferWithStrings(BytesToParse / encodedSize, encodedSize, encodedSize < 10 ? 10 : 1);
stringInputBuffersSegmented.Add(encodedSize, ReadOnlySequenceFactory.CreateWithContent(buffer, segmentSize: 128, addEmptySegmentDelimiters: false));
}
}
// Total number of bytes that each benchmark will parse.
// Measuring the time taken to parse buffer of given size makes it easier to compare parsing speed for different
// types and makes it easy to calculate the througput (in MB/s)
// 10800 bytes is chosen because it is divisible by all possible encoded sizes for all primitive types {1..10}
[Params(10080)]
public int BytesToParse { get; set; }
[Benchmark]
[Arguments(1)]
[Arguments(2)]
[Arguments(3)]
[Arguments(4)]
[Arguments(5)]
public int ParseRawVarint32_CodedInputStream(int encodedSize)
{
CodedInputStream cis = new CodedInputStream(varintInputBuffers[encodedSize]);
int sum = 0;
for (int i = 0; i < BytesToParse / encodedSize; i++)
{
sum += cis.ReadInt32();
}
return sum;
}
[Benchmark]
[Arguments(1)]
[Arguments(2)]
[Arguments(3)]
[Arguments(4)]
[Arguments(5)]
public int ParseRawVarint32_ParseContext(int encodedSize)
{
InitializeParseContext(varintInputBuffers[encodedSize], out ParseContext ctx);
int sum = 0;
for (int i = 0; i < BytesToParse / encodedSize; i++)
{
sum += ctx.ReadInt32();
}
return sum;
}
[Benchmark]
[Arguments(1)]
[Arguments(2)]
[Arguments(3)]
[Arguments(4)]
[Arguments(5)]
[Arguments(6)]
[Arguments(7)]
[Arguments(8)]
[Arguments(9)]
[Arguments(10)]
public long ParseRawVarint64_CodedInputStream(int encodedSize)
{
CodedInputStream cis = new CodedInputStream(varintInputBuffers[encodedSize]);
long sum = 0;
for (int i = 0; i < BytesToParse / encodedSize; i++)
{
sum += cis.ReadInt64();
}
return sum;
}
[Benchmark]
[Arguments(1)]
[Arguments(2)]
[Arguments(3)]
[Arguments(4)]
[Arguments(5)]
[Arguments(6)]
[Arguments(7)]
[Arguments(8)]
[Arguments(9)]
[Arguments(10)]
public long ParseRawVarint64_ParseContext(int encodedSize)
{
InitializeParseContext(varintInputBuffers[encodedSize], out ParseContext ctx);
long sum = 0;
for (int i = 0; i < BytesToParse / encodedSize; i++)
{
sum += ctx.ReadInt64();
}
return sum;
}
[Benchmark]
public uint ParseFixed32_CodedInputStream()
{
const int encodedSize = sizeof(uint);
CodedInputStream cis = new CodedInputStream(fixedIntInputBuffer);
uint sum = 0;
for (uint i = 0; i < BytesToParse / encodedSize; i++)
{
sum += cis.ReadFixed32();
}
return sum;
}
[Benchmark]
public uint ParseFixed32_ParseContext()
{
const int encodedSize = sizeof(uint);
InitializeParseContext(fixedIntInputBuffer, out ParseContext ctx);
uint sum = 0;
for (uint i = 0; i < BytesToParse / encodedSize; i++)
{
sum += ctx.ReadFixed32();
}
return sum;
}
[Benchmark]
public ulong ParseFixed64_CodedInputStream()
{
const int encodedSize = sizeof(ulong);
CodedInputStream cis = new CodedInputStream(fixedIntInputBuffer);
ulong sum = 0;
for (int i = 0; i < BytesToParse / encodedSize; i++)
{
sum += cis.ReadFixed64();
}
return sum;
}
[Benchmark]
public ulong ParseFixed64_ParseContext()
{
const int encodedSize = sizeof(ulong);
InitializeParseContext(fixedIntInputBuffer, out ParseContext ctx);
ulong sum = 0;
for (int i = 0; i < BytesToParse / encodedSize; i++)
{
sum += ctx.ReadFixed64();
}
return sum;
}
[Benchmark]
public float ParseRawFloat_CodedInputStream()
{
const int encodedSize = sizeof(float);
CodedInputStream cis = new CodedInputStream(floatInputBuffer);
float sum = 0;
for (int i = 0; i < BytesToParse / encodedSize; i++)
{
sum += cis.ReadFloat();
}
return sum;
}
[Benchmark]
public float ParseRawFloat_ParseContext()
{
const int encodedSize = sizeof(float);
InitializeParseContext(floatInputBuffer, out ParseContext ctx);
float sum = 0;
for (int i = 0; i < BytesToParse / encodedSize; i++)
{
sum += ctx.ReadFloat();
}
return sum;
}
[Benchmark]
public double ParseRawDouble_CodedInputStream()
{
const int encodedSize = sizeof(double);
CodedInputStream cis = new CodedInputStream(doubleInputBuffer);
double sum = 0;
for (int i = 0; i < BytesToParse / encodedSize; i++)
{
sum += cis.ReadDouble();
}
return sum;
}
[Benchmark]
public double ParseRawDouble_ParseContext()
{
const int encodedSize = sizeof(double);
InitializeParseContext(doubleInputBuffer, out ParseContext ctx);
double sum = 0;
for (int i = 0; i < BytesToParse / encodedSize; i++)
{
sum += ctx.ReadDouble();
}
return sum;
}
[Benchmark]
[ArgumentsSource(nameof(StringEncodedSizes))]
public int ParseString_CodedInputStream(int encodedSize)
{
CodedInputStream cis = new CodedInputStream(stringInputBuffers[encodedSize]);
int sum = 0;
for (int i = 0; i < BytesToParse / encodedSize; i++)
{
sum += cis.ReadString().Length;
}
return sum;
}
[Benchmark]
[ArgumentsSource(nameof(StringEncodedSizes))]
public int ParseString_ParseContext(int encodedSize)
{
InitializeParseContext(stringInputBuffers[encodedSize], out ParseContext ctx);
int sum = 0;
for (int i = 0; i < BytesToParse / encodedSize; i++)
{
sum += ctx.ReadString().Length;
}
return sum;
}
[Benchmark]
[ArgumentsSource(nameof(StringSegmentedEncodedSizes))]
public int ParseString_ParseContext_MultipleSegments(int encodedSize)
{
InitializeParseContext(stringInputBuffersSegmented[encodedSize], out ParseContext ctx);
int sum = 0;
for (int i = 0; i < BytesToParse / encodedSize; i++)
{
sum += ctx.ReadString().Length;
}
return sum;
}
[Benchmark]
[ArgumentsSource(nameof(StringEncodedSizes))]
public int ParseBytes_CodedInputStream(int encodedSize)
{
CodedInputStream cis = new CodedInputStream(stringInputBuffers[encodedSize]);
int sum = 0;
for (int i = 0; i < BytesToParse / encodedSize; i++)
{
sum += cis.ReadBytes().Length;
}
return sum;
}
[Benchmark]
[ArgumentsSource(nameof(StringEncodedSizes))]
public int ParseBytes_ParseContext(int encodedSize)
{
InitializeParseContext(stringInputBuffers[encodedSize], out ParseContext ctx);
int sum = 0;
for (int i = 0; i < BytesToParse / encodedSize; i++)
{
sum += ctx.ReadBytes().Length;
}
return sum;
}
[Benchmark]
[ArgumentsSource(nameof(StringSegmentedEncodedSizes))]
public int ParseBytes_ParseContext_MultipleSegments(int encodedSize)
{
InitializeParseContext(stringInputBuffersSegmented[encodedSize], out ParseContext ctx);
int sum = 0;
for (int i = 0; i < BytesToParse / encodedSize; i++)
{
sum += ctx.ReadBytes().Length;
}
return sum;
}
private static void InitializeParseContext(byte[] buffer, out ParseContext ctx)
{
ParseContext.Initialize(new ReadOnlySequence<byte>(buffer), out ctx);
}
private static void InitializeParseContext(ReadOnlySequence<byte> buffer, out ParseContext ctx)
{
ParseContext.Initialize(buffer, out ctx);
}
private static byte[] CreateBufferWithRandomVarints(Random random, int valueCount, int encodedSize, int paddingValueCount)
{
MemoryStream ms = new MemoryStream();
CodedOutputStream cos = new CodedOutputStream(ms);
for (int i = 0; i < valueCount + paddingValueCount; i++)
{
cos.WriteUInt64(RandomUnsignedVarint(random, encodedSize, false));
}
cos.Flush();
var buffer = ms.ToArray();
if (buffer.Length != encodedSize * (valueCount + paddingValueCount))
{
throw new InvalidOperationException($"Unexpected output buffer length {buffer.Length}");
}
return buffer;
}
private static byte[] CreateBufferWithRandomFloats(Random random, int valueCount, int paddingValueCount)
{
MemoryStream ms = new MemoryStream();
CodedOutputStream cos = new CodedOutputStream(ms);
for (int i = 0; i < valueCount + paddingValueCount; i++)
{
cos.WriteFloat((float)random.NextDouble());
}
cos.Flush();
var buffer = ms.ToArray();
return buffer;
}
private static byte[] CreateBufferWithRandomDoubles(Random random, int valueCount, int paddingValueCount)
{
MemoryStream ms = new MemoryStream();
CodedOutputStream cos = new CodedOutputStream(ms);
for (int i = 0; i < valueCount + paddingValueCount; i++)
{
cos.WriteDouble(random.NextDouble());
}
cos.Flush();
var buffer = ms.ToArray();
return buffer;
}
private static byte[] CreateBufferWithRandomData(Random random, int valueCount, int encodedSize, int paddingValueCount)
{
int bufferSize = (valueCount + paddingValueCount) * encodedSize;
var buffer = new byte[bufferSize];
random.NextBytes(buffer);
return buffer;
}
/// <summary>
/// Generate a random value that will take exactly "encodedSize" bytes when varint-encoded.
/// </summary>
public static ulong RandomUnsignedVarint(Random random, int encodedSize, bool fitsIn32Bits)
{
Span<byte> randomBytesBuffer = stackalloc byte[8];
if (encodedSize < 1 || encodedSize > 10 || (fitsIn32Bits && encodedSize > 5))
{
throw new ArgumentException("Illegal encodedSize value requested", nameof(encodedSize));
}
const int bitsPerByte = 7;
ulong result = 0;
while (true)
{
random.NextBytes(randomBytesBuffer);
ulong randomValue = BinaryPrimitives.ReadUInt64LittleEndian(randomBytesBuffer);
// only use the number of random bits we need
ulong bitmask = encodedSize < 10 ? ((1UL << (encodedSize * bitsPerByte)) - 1) : ulong.MaxValue;
result = randomValue & bitmask;
if (fitsIn32Bits)
{
// make sure the resulting value is representable by a uint.
result &= uint.MaxValue;
}
if (encodedSize == 10)
{
// for 10-byte values the highest bit always needs to be set (7*9=63)
result |= ulong.MaxValue;
break;
}
// some random values won't require the full "encodedSize" bytes, check that at least
// one of the top 7 bits is set. Retrying is fine since it only happens rarely
if (encodedSize == 1 || (result & (0x7FUL << ((encodedSize - 1) * bitsPerByte))) != 0)
{
break;
}
}
return result;
}
private static byte[] CreateBufferWithStrings(int valueCount, int encodedSize, int paddingValueCount)
{
var str = CreateStringWithEncodedSize(encodedSize);
MemoryStream ms = new MemoryStream();
CodedOutputStream cos = new CodedOutputStream(ms);
for (int i = 0; i < valueCount + paddingValueCount; i++)
{
cos.WriteString(str);
}
cos.Flush();
var buffer = ms.ToArray();
if (buffer.Length != encodedSize * (valueCount + paddingValueCount))
{
throw new InvalidOperationException($"Unexpected output buffer length {buffer.Length}");
}
return buffer;
}
public static string CreateStringWithEncodedSize(int encodedSize)
{
var str = new string('a', encodedSize);
while (CodedOutputStream.ComputeStringSize(str) > encodedSize)
{
str = str.Substring(1);
}
if (CodedOutputStream.ComputeStringSize(str) != encodedSize)
{
throw new InvalidOperationException($"Generated string with wrong encodedSize");
}
return str;
}
public static string CreateNonAsciiStringWithEncodedSize(int encodedSize)
{
if (encodedSize < 3)
{
throw new ArgumentException("Illegal encoded size for a string with non-ascii chars.");
}
var twoByteChar = '\u00DC'; // U-umlaut, UTF8 encoding has 2 bytes
var str = new string(twoByteChar, encodedSize / 2);
while (CodedOutputStream.ComputeStringSize(str) > encodedSize)
{
str = str.Substring(1);
}
// add padding of ascii characters to reach the desired encoded size.
while (CodedOutputStream.ComputeStringSize(str) < encodedSize)
{
str += 'a';
}
// Note that for a few specific encodedSize values, it might be impossible to generate
// the string with the desired encodedSize using the algorithm above. For testing purposes, checking that
// the encoded size we got is actually correct is good enough.
if (CodedOutputStream.ComputeStringSize(str) != encodedSize)
{
throw new InvalidOperationException($"Generated string with wrong encodedSize");
}
return str;
}
}
}

@ -1,47 +0,0 @@
#region Copyright notice and license
// Protocol Buffers - Google's data interchange format
// Copyright 2019 Google Inc. All rights reserved.
// https://github.com/protocolbuffers/protobuf
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#endregion
using BenchmarkDotNet.Running;
namespace Google.Protobuf.Benchmarks
{
class Program
{
// typical usage: dotnet run -c Release -f netcoreapp3.1
// (this can profile both .net core and .net framework; for some reason
// if you start from "-f net461", it goes horribly wrong)
public static void Main(string[] args)
{
BenchmarkSwitcher.FromAssembly(typeof(Program).Assembly).Run(args);
}
}
}

@ -1,198 +0,0 @@
#region Copyright notice and license
// Protocol Buffers - Google's data interchange format
// Copyright 2019 Google Inc. All rights reserved.
// https://github.com/protocolbuffers/protobuf
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#endregion
using BenchmarkDotNet.Attributes;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Buffers;
using Google.Protobuf.WellKnownTypes;
namespace Google.Protobuf.Benchmarks
{
/// <summary>
/// Benchmark that tests writing performance for various messages.
/// </summary>
[MemoryDiagnoser]
public class WriteMessagesBenchmark
{
const int MaxMessages = 100;
SubTest manyWrapperFieldsTest = new SubTest(ParseMessagesBenchmark.CreateManyWrapperFieldsMessage(), MaxMessages);
SubTest manyPrimitiveFieldsTest = new SubTest(ParseMessagesBenchmark.CreateManyPrimitiveFieldsMessage(), MaxMessages);
SubTest emptyMessageTest = new SubTest(new Empty(), MaxMessages);
public IEnumerable<int> MessageCountValues => new[] { 10, 100 };
[GlobalSetup]
public void GlobalSetup()
{
}
[Benchmark]
public byte[] ManyWrapperFieldsMessage_ToByteArray()
{
return manyWrapperFieldsTest.ToByteArray();
}
[Benchmark]
public byte[] ManyWrapperFieldsMessage_WriteToCodedOutputStream()
{
return manyWrapperFieldsTest.WriteToCodedOutputStream_PreAllocatedBuffer();
}
[Benchmark]
public byte[] ManyWrapperFieldsMessage_WriteToSpan()
{
return manyWrapperFieldsTest.WriteToSpan_PreAllocatedBuffer();
}
[Benchmark]
public byte[] ManyPrimitiveFieldsMessage_ToByteArray()
{
return manyPrimitiveFieldsTest.ToByteArray();
}
[Benchmark]
public byte[] ManyPrimitiveFieldsMessage_WriteToCodedOutputStream()
{
return manyPrimitiveFieldsTest.WriteToCodedOutputStream_PreAllocatedBuffer();
}
[Benchmark]
public byte[] ManyPrimitiveFieldsMessage_WriteToSpan()
{
return manyPrimitiveFieldsTest.WriteToSpan_PreAllocatedBuffer();
}
[Benchmark]
public byte[] EmptyMessage_ToByteArray()
{
return emptyMessageTest.ToByteArray();
}
[Benchmark]
public byte[] EmptyMessage_WriteToCodedOutputStream()
{
return emptyMessageTest.WriteToCodedOutputStream_PreAllocatedBuffer();
}
[Benchmark]
public byte[] EmptyMessage_WriteToSpan()
{
return emptyMessageTest.WriteToSpan_PreAllocatedBuffer();
}
[Benchmark]
[ArgumentsSource(nameof(MessageCountValues))]
public void ManyWrapperFieldsMessage_WriteDelimitedMessagesToCodedOutputStream(int messageCount)
{
manyWrapperFieldsTest.WriteDelimitedMessagesToCodedOutputStream_PreAllocatedBuffer(messageCount);
}
[Benchmark]
[ArgumentsSource(nameof(MessageCountValues))]
public void ManyWrapperFieldsMessage_WriteDelimitedMessagesToSpan(int messageCount)
{
manyWrapperFieldsTest.WriteDelimitedMessagesToSpan_PreAllocatedBuffer(messageCount);
}
[Benchmark]
[ArgumentsSource(nameof(MessageCountValues))]
public void ManyPrimitiveFieldsMessage_WriteDelimitedMessagesToCodedOutputStream(int messageCount)
{
manyPrimitiveFieldsTest.WriteDelimitedMessagesToCodedOutputStream_PreAllocatedBuffer(messageCount);
}
[Benchmark]
[ArgumentsSource(nameof(MessageCountValues))]
public void ManyPrimitiveFieldsMessage_WriteDelimitedMessagesToSpan(int messageCount)
{
manyPrimitiveFieldsTest.WriteDelimitedMessagesToSpan_PreAllocatedBuffer(messageCount);
}
private class SubTest
{
private readonly IMessage message;
private readonly byte[] outputBuffer;
private readonly byte[] multipleMessagesOutputBuffer;
public SubTest(IMessage message, int maxMessageCount)
{
this.message = message;
int messageSize = message.CalculateSize();
this.outputBuffer = new byte[messageSize];
this.multipleMessagesOutputBuffer = new byte[maxMessageCount * (messageSize + CodedOutputStream.ComputeLengthSize(messageSize))];
}
public byte[] ToByteArray() => message.ToByteArray();
public byte[] WriteToCodedOutputStream_PreAllocatedBuffer()
{
var cos = new CodedOutputStream(outputBuffer); // use pre-existing output buffer
message.WriteTo(cos);
return outputBuffer;
}
public byte[] WriteToSpan_PreAllocatedBuffer()
{
var span = new Span<byte>(outputBuffer); // use pre-existing output buffer
message.WriteTo(span);
return outputBuffer;
}
public byte[] WriteDelimitedMessagesToCodedOutputStream_PreAllocatedBuffer(int messageCount)
{
var cos = new CodedOutputStream(multipleMessagesOutputBuffer); // use pre-existing output buffer
for (int i = 0; i < messageCount; i++)
{
cos.WriteMessage(message);
}
return multipleMessagesOutputBuffer;
}
public byte[] WriteDelimitedMessagesToSpan_PreAllocatedBuffer(int messageCount)
{
var span = new Span<byte>(multipleMessagesOutputBuffer); // use pre-existing output buffer
WriteContext.Initialize(ref span, out WriteContext ctx);
for (int i = 0; i < messageCount; i++)
{
ctx.WriteMessage(message);
}
return multipleMessagesOutputBuffer;
}
}
}
}

@ -1,516 +0,0 @@
#region Copyright notice and license
// Protocol Buffers - Google's data interchange format
// Copyright 2019 Google Inc. All rights reserved.
// https://github.com/protocolbuffers/protobuf
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#endregion
using BenchmarkDotNet.Attributes;
using System;
using System.Collections.Generic;
using System.Text;
namespace Google.Protobuf.Benchmarks
{
/// <summary>
/// Benchmarks throughput when writing raw primitives.
/// </summary>
[MemoryDiagnoser]
public class WriteRawPrimitivesBenchmark
{
// key is the encodedSize of varint values
Dictionary<int, uint[]> varint32Values;
Dictionary<int, ulong[]> varint64Values;
double[] doubleValues;
float[] floatValues;
// key is the encodedSize of string values
Dictionary<int, string[]> stringValues;
// key is the encodedSize of string values
Dictionary<int, string[]> nonAsciiStringValues;
// key is the encodedSize of string values
Dictionary<int, ByteString[]> byteStringValues;
// the buffer to which all the data will be written
byte[] outputBuffer;
Random random = new Random(417384220); // random but deterministic seed
public IEnumerable<int> StringEncodedSizes => new[] { 1, 4, 10, 105, 10080 };
public IEnumerable<int> NonAsciiStringEncodedSizes => new[] { 4, 10, 105, 10080 };
[GlobalSetup]
public void GlobalSetup()
{
outputBuffer = new byte[BytesToWrite];
varint32Values = new Dictionary<int, uint[]>();
varint64Values = new Dictionary<int, ulong[]>();
for (int encodedSize = 1; encodedSize <= 10; encodedSize++)
{
if (encodedSize <= 5)
{
varint32Values.Add(encodedSize, CreateRandomVarints32(random, BytesToWrite / encodedSize, encodedSize));
}
varint64Values.Add(encodedSize, CreateRandomVarints64(random, BytesToWrite / encodedSize, encodedSize));
}
doubleValues = CreateRandomDoubles(random, BytesToWrite / sizeof(double));
floatValues = CreateRandomFloats(random, BytesToWrite / sizeof(float));
stringValues = new Dictionary<int, string[]>();
byteStringValues = new Dictionary<int, ByteString[]>();
foreach(var encodedSize in StringEncodedSizes)
{
stringValues.Add(encodedSize, CreateStrings(BytesToWrite / encodedSize, encodedSize));
byteStringValues.Add(encodedSize, CreateByteStrings(BytesToWrite / encodedSize, encodedSize));
}
nonAsciiStringValues = new Dictionary<int, string[]>();
foreach(var encodedSize in NonAsciiStringEncodedSizes)
{
nonAsciiStringValues.Add(encodedSize, CreateNonAsciiStrings(BytesToWrite / encodedSize, encodedSize));
}
}
// Total number of bytes that each benchmark will write.
// Measuring the time taken to write buffer of given size makes it easier to compare parsing speed for different
// types and makes it easy to calculate the througput (in MB/s)
// 10800 bytes is chosen because it is divisible by all possible encoded sizes for all primitive types {1..10}
[Params(10080)]
public int BytesToWrite { get; set; }
[Benchmark]
[Arguments(1)]
[Arguments(2)]
[Arguments(3)]
[Arguments(4)]
[Arguments(5)]
public void WriteRawVarint32_CodedOutputStream(int encodedSize)
{
var values = varint32Values[encodedSize];
var cos = new CodedOutputStream(outputBuffer);
for (int i = 0; i < values.Length; i++)
{
cos.WriteRawVarint32(values[i]);
}
cos.Flush();
cos.CheckNoSpaceLeft();
}
[Benchmark]
[Arguments(1)]
[Arguments(2)]
[Arguments(3)]
[Arguments(4)]
[Arguments(5)]
public void WriteRawVarint32_WriteContext(int encodedSize)
{
var values = varint32Values[encodedSize];
var span = new Span<byte>(outputBuffer);
WriteContext.Initialize(ref span, out WriteContext ctx);
for (int i = 0; i < values.Length; i++)
{
ctx.WriteUInt32(values[i]);
}
ctx.Flush();
ctx.CheckNoSpaceLeft();
}
[Benchmark]
[Arguments(1)]
[Arguments(2)]
[Arguments(3)]
[Arguments(4)]
[Arguments(5)]
[Arguments(6)]
[Arguments(7)]
[Arguments(8)]
[Arguments(9)]
[Arguments(10)]
public void WriteRawVarint64_CodedOutputStream(int encodedSize)
{
var values = varint64Values[encodedSize];
var cos = new CodedOutputStream(outputBuffer);
for (int i = 0; i < values.Length; i++)
{
cos.WriteRawVarint64(values[i]);
}
cos.Flush();
cos.CheckNoSpaceLeft();
}
[Benchmark]
[Arguments(1)]
[Arguments(2)]
[Arguments(3)]
[Arguments(4)]
[Arguments(5)]
[Arguments(6)]
[Arguments(7)]
[Arguments(8)]
[Arguments(9)]
[Arguments(10)]
public void WriteRawVarint64_WriteContext(int encodedSize)
{
var values = varint64Values[encodedSize];
var span = new Span<byte>(outputBuffer);
WriteContext.Initialize(ref span, out WriteContext ctx);
for (int i = 0; i < values.Length; i++)
{
ctx.WriteUInt64(values[i]);
}
ctx.Flush();
ctx.CheckNoSpaceLeft();
}
[Benchmark]
public void WriteFixed32_CodedOutputStream()
{
const int encodedSize = sizeof(uint);
var cos = new CodedOutputStream(outputBuffer);
for (int i = 0; i < BytesToWrite / encodedSize; i++)
{
cos.WriteFixed32(12345);
}
cos.Flush();
cos.CheckNoSpaceLeft();
}
[Benchmark]
public void WriteFixed32_WriteContext()
{
const int encodedSize = sizeof(uint);
var span = new Span<byte>(outputBuffer);
WriteContext.Initialize(ref span, out WriteContext ctx);
for (uint i = 0; i < BytesToWrite / encodedSize; i++)
{
ctx.WriteFixed32(12345);
}
ctx.Flush();
ctx.CheckNoSpaceLeft();
}
[Benchmark]
public void WriteFixed64_CodedOutputStream()
{
const int encodedSize = sizeof(ulong);
var cos = new CodedOutputStream(outputBuffer);
for(int i = 0; i < BytesToWrite / encodedSize; i++)
{
cos.WriteFixed64(123456789);
}
cos.Flush();
cos.CheckNoSpaceLeft();
}
[Benchmark]
public void WriteFixed64_WriteContext()
{
const int encodedSize = sizeof(ulong);
var span = new Span<byte>(outputBuffer);
WriteContext.Initialize(ref span, out WriteContext ctx);
for (uint i = 0; i < BytesToWrite / encodedSize; i++)
{
ctx.WriteFixed64(123456789);
}
ctx.Flush();
ctx.CheckNoSpaceLeft();
}
[Benchmark]
public void WriteRawTag_OneByte_WriteContext()
{
const int encodedSize = 1;
var span = new Span<byte>(outputBuffer);
WriteContext.Initialize(ref span, out WriteContext ctx);
for (uint i = 0; i < BytesToWrite / encodedSize; i++)
{
ctx.WriteRawTag(16);
}
ctx.Flush();
ctx.CheckNoSpaceLeft();
}
[Benchmark]
public void WriteRawTag_TwoBytes_WriteContext()
{
const int encodedSize = 2;
var span = new Span<byte>(outputBuffer);
WriteContext.Initialize(ref span, out WriteContext ctx);
for (uint i = 0; i < BytesToWrite / encodedSize; i++)
{
ctx.WriteRawTag(137, 6);
}
ctx.Flush();
ctx.CheckNoSpaceLeft();
}
[Benchmark]
public void WriteRawTag_ThreeBytes_WriteContext()
{
const int encodedSize = 3;
var span = new Span<byte>(outputBuffer);
WriteContext.Initialize(ref span, out WriteContext ctx);
for (uint i = 0; i < BytesToWrite / encodedSize; i++)
{
ctx.WriteRawTag(160, 131, 1);
}
ctx.Flush();
ctx.CheckNoSpaceLeft();
}
[Benchmark]
public void Baseline_WriteContext()
{
var span = new Span<byte>(outputBuffer);
WriteContext.Initialize(ref span, out WriteContext ctx);
ctx.state.position = outputBuffer.Length;
ctx.Flush();
ctx.CheckNoSpaceLeft();
}
[Benchmark]
public void WriteRawFloat_CodedOutputStream()
{
var cos = new CodedOutputStream(outputBuffer);
foreach (var value in floatValues)
{
cos.WriteFloat(value);
}
cos.Flush();
cos.CheckNoSpaceLeft();
}
[Benchmark]
public void WriteRawFloat_WriteContext()
{
var span = new Span<byte>(outputBuffer);
WriteContext.Initialize(ref span, out WriteContext ctx);
foreach (var value in floatValues)
{
ctx.WriteFloat(value);
}
ctx.Flush();
ctx.CheckNoSpaceLeft();
}
[Benchmark]
public void WriteRawDouble_CodedOutputStream()
{
var cos = new CodedOutputStream(outputBuffer);
foreach (var value in doubleValues)
{
cos.WriteDouble(value);
}
cos.Flush();
cos.CheckNoSpaceLeft();
}
[Benchmark]
public void WriteRawDouble_WriteContext()
{
var span = new Span<byte>(outputBuffer);
WriteContext.Initialize(ref span, out WriteContext ctx);
foreach (var value in doubleValues)
{
ctx.WriteDouble(value);
}
ctx.Flush();
ctx.CheckNoSpaceLeft();
}
[Benchmark]
[ArgumentsSource(nameof(StringEncodedSizes))]
public void WriteString_CodedOutputStream(int encodedSize)
{
var values = stringValues[encodedSize];
var cos = new CodedOutputStream(outputBuffer);
foreach (var value in values)
{
cos.WriteString(value);
}
cos.Flush();
cos.CheckNoSpaceLeft();
}
[Benchmark]
[ArgumentsSource(nameof(StringEncodedSizes))]
public void WriteString_WriteContext(int encodedSize)
{
var values = stringValues[encodedSize];
var span = new Span<byte>(outputBuffer);
WriteContext.Initialize(ref span, out WriteContext ctx);
foreach (var value in values)
{
ctx.WriteString(value);
}
ctx.Flush();
ctx.CheckNoSpaceLeft();
}
[Benchmark]
[ArgumentsSource(nameof(NonAsciiStringEncodedSizes))]
public void WriteNonAsciiString_CodedOutputStream(int encodedSize)
{
var values = nonAsciiStringValues[encodedSize];
var cos = new CodedOutputStream(outputBuffer);
foreach (var value in values)
{
cos.WriteString(value);
}
cos.Flush();
cos.CheckNoSpaceLeft();
}
[Benchmark]
[ArgumentsSource(nameof(NonAsciiStringEncodedSizes))]
public void WriteNonAsciiString_WriteContext(int encodedSize)
{
var values = nonAsciiStringValues[encodedSize];
var span = new Span<byte>(outputBuffer);
WriteContext.Initialize(ref span, out WriteContext ctx);
foreach (var value in values)
{
ctx.WriteString(value);
}
ctx.Flush();
ctx.CheckNoSpaceLeft();
}
[Benchmark]
[ArgumentsSource(nameof(StringEncodedSizes))]
public void WriteBytes_CodedOutputStream(int encodedSize)
{
var values = byteStringValues[encodedSize];
var cos = new CodedOutputStream(outputBuffer);
foreach (var value in values)
{
cos.WriteBytes(value);
}
cos.Flush();
cos.CheckNoSpaceLeft();
}
[Benchmark]
[ArgumentsSource(nameof(StringEncodedSizes))]
public void WriteBytes_WriteContext(int encodedSize)
{
var values = byteStringValues[encodedSize];
var span = new Span<byte>(outputBuffer);
WriteContext.Initialize(ref span, out WriteContext ctx);
foreach (var value in values)
{
ctx.WriteBytes(value);
}
ctx.Flush();
ctx.CheckNoSpaceLeft();
}
private static uint[] CreateRandomVarints32(Random random, int valueCount, int encodedSize)
{
var result = new uint[valueCount];
for (int i = 0; i < valueCount; i++)
{
result[i] = (uint) ParseRawPrimitivesBenchmark.RandomUnsignedVarint(random, encodedSize, true);
}
return result;
}
private static ulong[] CreateRandomVarints64(Random random, int valueCount, int encodedSize)
{
var result = new ulong[valueCount];
for (int i = 0; i < valueCount; i++)
{
result[i] = ParseRawPrimitivesBenchmark.RandomUnsignedVarint(random, encodedSize, false);
}
return result;
}
private static float[] CreateRandomFloats(Random random, int valueCount)
{
var result = new float[valueCount];
for (int i = 0; i < valueCount; i++)
{
result[i] = (float)random.NextDouble();
}
return result;
}
private static double[] CreateRandomDoubles(Random random, int valueCount)
{
var result = new double[valueCount];
for (int i = 0; i < valueCount; i++)
{
result[i] = random.NextDouble();
}
return result;
}
private static string[] CreateStrings(int valueCount, int encodedSize)
{
var str = ParseRawPrimitivesBenchmark.CreateStringWithEncodedSize(encodedSize);
var result = new string[valueCount];
for (int i = 0; i < valueCount; i++)
{
result[i] = str;
}
return result;
}
private static string[] CreateNonAsciiStrings(int valueCount, int encodedSize)
{
var str = ParseRawPrimitivesBenchmark.CreateNonAsciiStringWithEncodedSize(encodedSize);
var result = new string[valueCount];
for (int i = 0; i < valueCount; i++)
{
result[i] = str;
}
return result;
}
private static ByteString[] CreateByteStrings(int valueCount, int encodedSize)
{
var str = ParseRawPrimitivesBenchmark.CreateStringWithEncodedSize(encodedSize);
var result = new ByteString[valueCount];
for (int i = 0; i < valueCount; i++)
{
result[i] = ByteString.CopyFrom(Encoding.UTF8.GetBytes(str));
}
return result;
}
}
}

@ -1,237 +0,0 @@
syntax = "proto3";
package google.protobuf.benchmarks;
import "google/protobuf/wrappers.proto";
// a message that has a large number of wrapper fields
// obfuscated version of an internal message
message ManyWrapperFieldsMessage {
google.protobuf.DoubleValue double_field_95 = 95;
google.protobuf.DoubleValue double_field_1 = 1;
google.protobuf.DoubleValue double_field_79 = 79;
google.protobuf.Int64Value int64_field_2 = 2;
google.protobuf.DoubleValue double_field_96 = 96;
google.protobuf.Int64Value int64_field_3 = 3;
google.protobuf.Int64Value int64_field_4 = 4;
google.protobuf.DoubleValue double_field_97 = 97;
google.protobuf.DoubleValue double_field_65 = 65;
google.protobuf.DoubleValue double_field_66 = 66;
google.protobuf.DoubleValue double_field_7 = 7;
google.protobuf.DoubleValue double_field_62 = 62;
google.protobuf.DoubleValue double_field_118 = 118;
google.protobuf.DoubleValue double_field_119 = 119;
google.protobuf.DoubleValue double_field_67 = 67;
google.protobuf.DoubleValue double_field_120 = 120;
google.protobuf.DoubleValue double_field_121 = 121;
google.protobuf.DoubleValue double_field_122 = 122;
google.protobuf.DoubleValue double_field_123 = 123;
google.protobuf.DoubleValue double_field_124 = 124;
google.protobuf.DoubleValue double_field_8 = 8;
google.protobuf.DoubleValue double_field_9 = 9;
google.protobuf.DoubleValue double_field_98 = 98;
google.protobuf.DoubleValue double_field_10 = 10;
google.protobuf.DoubleValue double_field_11 = 11;
google.protobuf.DoubleValue double_field_99 = 99;
google.protobuf.DoubleValue double_field_84 = 84;
google.protobuf.DoubleValue double_field_14 = 14;
google.protobuf.DoubleValue double_field_77 = 77;
google.protobuf.DoubleValue double_field_15 = 15;
google.protobuf.Int64Value int64_field_19 = 19;
google.protobuf.Int64Value int64_field_115 = 115;
google.protobuf.DoubleValue double_field_116 = 116;
google.protobuf.Int64Value int64_field_117 = 117;
google.protobuf.DoubleValue double_field_20 = 20;
google.protobuf.DoubleValue double_field_21 = 21;
google.protobuf.StringValue string_field_73 = 73;
google.protobuf.StringValue string_field_74 = 74;
google.protobuf.DoubleValue double_field_22 = 22;
google.protobuf.DoubleValue double_field_69 = 69;
google.protobuf.DoubleValue double_field_70 = 70;
google.protobuf.DoubleValue double_field_71 = 71;
google.protobuf.DoubleValue double_field_72 = 72;
google.protobuf.DoubleValue double_field_25 = 25;
google.protobuf.Int64Value int64_field_26 = 26;
google.protobuf.DoubleValue double_field_68 = 68;
google.protobuf.DoubleValue double_field_28 = 28;
google.protobuf.DoubleValue double_field_106 = 106;
google.protobuf.DoubleValue double_field_29 = 29;
google.protobuf.DoubleValue double_field_30 = 30;
google.protobuf.DoubleValue double_field_101 = 101;
google.protobuf.DoubleValue double_field_102 = 102;
google.protobuf.DoubleValue double_field_103 = 103;
google.protobuf.DoubleValue double_field_104 = 104;
google.protobuf.DoubleValue double_field_105 = 105;
google.protobuf.DoubleValue double_field_31 = 31;
google.protobuf.Int64Value int64_field_32 = 32;
google.protobuf.DoubleValue double_field_75 = 75;
google.protobuf.DoubleValue double_field_129 = 129;
int32 enum_field_80 = 80;
int32 enum_field_81 = 81;
google.protobuf.Int64Value int64_field_82 = 82;
int32 enum_field_83 = 83;
google.protobuf.Int64Value int64_field_85 = 85;
google.protobuf.Int64Value int64_field_86 = 86;
google.protobuf.Int64Value int64_field_87 = 87;
google.protobuf.Int64Value int64_field_125 = 125;
google.protobuf.Int64Value int64_field_37 = 37;
google.protobuf.DoubleValue double_field_38 = 38;
google.protobuf.Int64Value interactions = 39;
repeated int32 repeated_int_field_100 = 100;
google.protobuf.DoubleValue double_field_40 = 40;
google.protobuf.Int64Value int64_field_41 = 41;
google.protobuf.Int64Value int64_field_126 = 126;
google.protobuf.Int64Value int64_field_127 = 127;
google.protobuf.DoubleValue double_field_128 = 128;
google.protobuf.DoubleValue double_field_109 = 109;
google.protobuf.Int64Value int64_field_110 = 110;
google.protobuf.DoubleValue double_field_111 = 111;
google.protobuf.Int64Value int64_field_112 = 112;
google.protobuf.DoubleValue double_field_113 = 113;
google.protobuf.Int64Value int64_field_114 = 114;
google.protobuf.DoubleValue double_field_42 = 42;
google.protobuf.Int64Value int64_field_43 = 43;
google.protobuf.Int64Value int64_field_44 = 44;
google.protobuf.DoubleValue double_field_45 = 45;
google.protobuf.DoubleValue double_field_46 = 46;
google.protobuf.DoubleValue double_field_78 = 78;
google.protobuf.DoubleValue double_field_88 = 88;
google.protobuf.DoubleValue double_field_47 = 47;
google.protobuf.DoubleValue double_field_89 = 89;
google.protobuf.DoubleValue double_field_48 = 48;
google.protobuf.DoubleValue double_field_49 = 49;
google.protobuf.DoubleValue double_field_50 = 50;
google.protobuf.DoubleValue double_field_90 = 90;
google.protobuf.DoubleValue double_field_51 = 51;
google.protobuf.DoubleValue double_field_91 = 91;
google.protobuf.DoubleValue double_field_92 = 92;
google.protobuf.Int64Value int64_field_107 = 107;
google.protobuf.DoubleValue double_field_93 = 93;
google.protobuf.DoubleValue double_field_108 = 108;
google.protobuf.DoubleValue double_field_52 = 52;
google.protobuf.DoubleValue double_field_53 = 53;
google.protobuf.DoubleValue double_field_94 = 94;
google.protobuf.DoubleValue double_field_54 = 54;
google.protobuf.DoubleValue double_field_55 = 55;
google.protobuf.DoubleValue double_field_56 = 56;
google.protobuf.DoubleValue double_field_57 = 57;
google.protobuf.DoubleValue double_field_58 = 58;
google.protobuf.Int64Value int64_field_59 = 59;
google.protobuf.Int64Value int64_field_60 = 60;
}
// same as ManyWrapperFieldsMessages, but with primitive fields
// for comparison.
message ManyPrimitiveFieldsMessage {
double double_field_95 = 95;
double double_field_1 = 1;
double double_field_79 = 79;
int64 int64_field_2 = 2;
double double_field_96 = 96;
int64 int64_field_3 = 3;
int64 int64_field_4 = 4;
double double_field_97 = 97;
double double_field_65 = 65;
double double_field_66 = 66;
double double_field_7 = 7;
double double_field_62 = 62;
double double_field_118 = 118;
double double_field_119 = 119;
double double_field_67 = 67;
double double_field_120 = 120;
double double_field_121 = 121;
double double_field_122 = 122;
double double_field_123 = 123;
double double_field_124 = 124;
double double_field_8 = 8;
double double_field_9 = 9;
double double_field_98 = 98;
double double_field_10 = 10;
double double_field_11 = 11;
double double_field_99 = 99;
double double_field_84 = 84;
double double_field_14 = 14;
double double_field_77 = 77;
double double_field_15 = 15;
int64 int64_field_19 = 19;
int64 int64_field_115 = 115;
double double_field_116 = 116;
int64 int64_field_117 = 117;
double double_field_20 = 20;
double double_field_21 = 21;
string string_field_73 = 73;
string string_field_74 = 74;
double double_field_22 = 22;
double double_field_69 = 69;
double double_field_70 = 70;
double double_field_71 = 71;
double double_field_72 = 72;
double double_field_25 = 25;
int64 int64_field_26 = 26;
double double_field_68 = 68;
double double_field_28 = 28;
double double_field_106 = 106;
double double_field_29 = 29;
double double_field_30 = 30;
double double_field_101 = 101;
double double_field_102 = 102;
double double_field_103 = 103;
double double_field_104 = 104;
double double_field_105 = 105;
double double_field_31 = 31;
int64 int64_field_32 = 32;
double double_field_75 = 75;
double double_field_129 = 129;
int32 enum_field_80 = 80;
int32 enum_field_81 = 81;
int64 int64_field_82 = 82;
int32 enum_field_83 = 83;
int64 int64_field_85 = 85;
int64 int64_field_86 = 86;
int64 int64_field_87 = 87;
int64 int64_field_125 = 125;
int64 int64_field_37 = 37;
double double_field_38 = 38;
int64 interactions = 39;
repeated int32 repeated_int_field_100 = 100;
double double_field_40 = 40;
int64 int64_field_41 = 41;
int64 int64_field_126 = 126;
int64 int64_field_127 = 127;
double double_field_128 = 128;
double double_field_109 = 109;
int64 int64_field_110 = 110;
double double_field_111 = 111;
int64 int64_field_112 = 112;
double double_field_113 = 113;
int64 int64_field_114 = 114;
double double_field_42 = 42;
int64 int64_field_43 = 43;
int64 int64_field_44 = 44;
double double_field_45 = 45;
double double_field_46 = 46;
double double_field_78 = 78;
double double_field_88 = 88;
double double_field_47 = 47;
double double_field_89 = 89;
double double_field_48 = 48;
double double_field_49 = 49;
double double_field_50 = 50;
double double_field_90 = 90;
double double_field_51 = 51;
double double_field_91 = 91;
double double_field_92 = 92;
int64 int64_field_107 = 107;
double double_field_93 = 93;
double double_field_108 = 108;
double double_field_52 = 52;
double double_field_53 = 53;
double double_field_94 = 94;
double double_field_54 = 54;
double double_field_55 = 55;
double double_field_56 = 56;
double double_field_57 = 57;
double double_field_58 = 58;
int64 int64_field_59 = 59;
int64 int64_field_60 = 60;
}

@ -30,43 +30,44 @@ namespace UnitTest.Issues.TestProtos {
"EiwKBXZhbHVlGAEgASgOMh0udW5pdHRlc3RfaXNzdWVzLk5lZ2F0aXZlRW51",
"bRIxCgZ2YWx1ZXMYAiADKA4yHS51bml0dGVzdF9pc3N1ZXMuTmVnYXRpdmVF",
"bnVtQgIQABI4Cg1wYWNrZWRfdmFsdWVzGAMgAygOMh0udW5pdHRlc3RfaXNz",
"dWVzLk5lZ2F0aXZlRW51bUICEAEiEQoPRGVwcmVjYXRlZENoaWxkIrkCChdE",
"ZXByZWNhdGVkRmllbGRzTWVzc2FnZRIaCg5QcmltaXRpdmVWYWx1ZRgBIAEo",
"BUICGAESGgoOUHJpbWl0aXZlQXJyYXkYAiADKAVCAhgBEjoKDE1lc3NhZ2VW",
"YWx1ZRgDIAEoCzIgLnVuaXR0ZXN0X2lzc3Vlcy5EZXByZWNhdGVkQ2hpbGRC",
"AhgBEjoKDE1lc3NhZ2VBcnJheRgEIAMoCzIgLnVuaXR0ZXN0X2lzc3Vlcy5E",
"ZXByZWNhdGVkQ2hpbGRCAhgBEjYKCUVudW1WYWx1ZRgFIAEoDjIfLnVuaXR0",
"ZXN0X2lzc3Vlcy5EZXByZWNhdGVkRW51bUICGAESNgoJRW51bUFycmF5GAYg",
"AygOMh8udW5pdHRlc3RfaXNzdWVzLkRlcHJlY2F0ZWRFbnVtQgIYASIZCglJ",
"dGVtRmllbGQSDAoEaXRlbRgBIAEoBSJECg1SZXNlcnZlZE5hbWVzEg0KBXR5",
"cGVzGAEgASgFEhIKCmRlc2NyaXB0b3IYAiABKAUaEAoOU29tZU5lc3RlZFR5",
"cGUioAEKFVRlc3RKc29uRmllbGRPcmRlcmluZxITCgtwbGFpbl9pbnQzMhgE",
"IAEoBRITCglvMV9zdHJpbmcYAiABKAlIABISCghvMV9pbnQzMhgFIAEoBUgA",
"EhQKDHBsYWluX3N0cmluZxgBIAEoCRISCghvMl9pbnQzMhgGIAEoBUgBEhMK",
"CW8yX3N0cmluZxgDIAEoCUgBQgQKAm8xQgQKAm8yIksKDFRlc3RKc29uTmFt",
"ZRIMCgRuYW1lGAEgASgJEhkKC2Rlc2NyaXB0aW9uGAIgASgJUgRkZXNjEhIK",
"BGd1aWQYAyABKAlSBGV4aWQifwoMT25lb2ZNZXJnaW5nEg4KBHRleHQYASAB",
"KAlIABI2CgZuZXN0ZWQYAiABKAsyJC51bml0dGVzdF9pc3N1ZXMuT25lb2ZN",
"ZXJnaW5nLk5lc3RlZEgAGh4KBk5lc3RlZBIJCgF4GAEgASgFEgkKAXkYAiAB",
"KAVCBwoFdmFsdWUiawoWTnVsbFZhbHVlT3V0c2lkZVN0cnVjdBIWCgxzdHJp",
"bmdfdmFsdWUYASABKAlIABIwCgpudWxsX3ZhbHVlGAIgASgOMhouZ29vZ2xl",
"LnByb3RvYnVmLk51bGxWYWx1ZUgAQgcKBXZhbHVlIkUKE051bGxWYWx1ZU5v",
"dEluT25lb2YSLgoKbnVsbF92YWx1ZRgCIAEoDjIaLmdvb2dsZS5wcm90b2J1",
"Zi5OdWxsVmFsdWUiYAoXTWl4ZWRSZWd1bGFyQW5kT3B0aW9uYWwSFQoNcmVn",
"dWxhcl9maWVsZBgBIAEoCRIbCg5vcHRpb25hbF9maWVsZBgCIAEoCUgAiAEB",
"QhEKD19vcHRpb25hbF9maWVsZCI5ChJPbmVvZldpdGhOb25lRmllbGQSCwoB",
"eBgBIAEoCUgAEg4KBG5vbmUYAiABKAlIAEIGCgR0ZXN0IjUKEU9uZW9mV2l0",
"aE5vbmVOYW1lEgsKAXgYASABKAlIABILCgF5GAIgASgJSABCBgoEbm9uZSKT",
"AgoZRGlzYW1iaWd1YXRlQ29tbW9uTWVtYmVycxIjChtkaXNhbWJpZ3VhdGVf",
"Y29tbW9uX21lbWJlcnMYASABKAUSDQoFdHlwZXMYAiABKAUSEgoKZGVzY3Jp",
"cHRvchgDIAEoBRIOCgZlcXVhbHMYBCABKAUSEQoJdG9fc3RyaW5nGAUgASgF",
"EhUKDWdldF9oYXNoX2NvZGUYBiABKAUSEAoId3JpdGVfdG8YByABKAUSDQoF",
"Y2xvbmUYCCABKAUSFgoOY2FsY3VsYXRlX3NpemUYCSABKAUSEgoKbWVyZ2Vf",
"ZnJvbRgKIAEoBRIXCg9vbl9jb25zdHJ1Y3Rpb24YCyABKAUSDgoGcGFyc2Vy",
"GAwgASgFKlUKDE5lZ2F0aXZlRW51bRIWChJORUdBVElWRV9FTlVNX1pFUk8Q",
"ABIWCglGaXZlQmVsb3cQ+///////////ARIVCghNaW51c09uZRD/////////",
"//8BKi4KDkRlcHJlY2F0ZWRFbnVtEhMKD0RFUFJFQ0FURURfWkVSTxAAEgcK",
"A29uZRABQh2qAhpVbml0VGVzdC5Jc3N1ZXMuVGVzdFByb3Rvc2IGcHJvdG8z"));
"dWVzLk5lZ2F0aXZlRW51bUICEAEiFQoPRGVwcmVjYXRlZENoaWxkOgIYASK5",
"AgoXRGVwcmVjYXRlZEZpZWxkc01lc3NhZ2USGgoOUHJpbWl0aXZlVmFsdWUY",
"ASABKAVCAhgBEhoKDlByaW1pdGl2ZUFycmF5GAIgAygFQgIYARI6CgxNZXNz",
"YWdlVmFsdWUYAyABKAsyIC51bml0dGVzdF9pc3N1ZXMuRGVwcmVjYXRlZENo",
"aWxkQgIYARI6CgxNZXNzYWdlQXJyYXkYBCADKAsyIC51bml0dGVzdF9pc3N1",
"ZXMuRGVwcmVjYXRlZENoaWxkQgIYARI2CglFbnVtVmFsdWUYBSABKA4yHy51",
"bml0dGVzdF9pc3N1ZXMuRGVwcmVjYXRlZEVudW1CAhgBEjYKCUVudW1BcnJh",
"eRgGIAMoDjIfLnVuaXR0ZXN0X2lzc3Vlcy5EZXByZWNhdGVkRW51bUICGAEi",
"GQoJSXRlbUZpZWxkEgwKBGl0ZW0YASABKAUiRAoNUmVzZXJ2ZWROYW1lcxIN",
"CgV0eXBlcxgBIAEoBRISCgpkZXNjcmlwdG9yGAIgASgFGhAKDlNvbWVOZXN0",
"ZWRUeXBlIqABChVUZXN0SnNvbkZpZWxkT3JkZXJpbmcSEwoLcGxhaW5faW50",
"MzIYBCABKAUSEwoJbzFfc3RyaW5nGAIgASgJSAASEgoIbzFfaW50MzIYBSAB",
"KAVIABIUCgxwbGFpbl9zdHJpbmcYASABKAkSEgoIbzJfaW50MzIYBiABKAVI",
"ARITCglvMl9zdHJpbmcYAyABKAlIAUIECgJvMUIECgJvMiJLCgxUZXN0SnNv",
"bk5hbWUSDAoEbmFtZRgBIAEoCRIZCgtkZXNjcmlwdGlvbhgCIAEoCVIEZGVz",
"YxISCgRndWlkGAMgASgJUgRleGlkIn8KDE9uZW9mTWVyZ2luZxIOCgR0ZXh0",
"GAEgASgJSAASNgoGbmVzdGVkGAIgASgLMiQudW5pdHRlc3RfaXNzdWVzLk9u",
"ZW9mTWVyZ2luZy5OZXN0ZWRIABoeCgZOZXN0ZWQSCQoBeBgBIAEoBRIJCgF5",
"GAIgASgFQgcKBXZhbHVlImsKFk51bGxWYWx1ZU91dHNpZGVTdHJ1Y3QSFgoM",
"c3RyaW5nX3ZhbHVlGAEgASgJSAASMAoKbnVsbF92YWx1ZRgCIAEoDjIaLmdv",
"b2dsZS5wcm90b2J1Zi5OdWxsVmFsdWVIAEIHCgV2YWx1ZSJFChNOdWxsVmFs",
"dWVOb3RJbk9uZW9mEi4KCm51bGxfdmFsdWUYAiABKA4yGi5nb29nbGUucHJv",
"dG9idWYuTnVsbFZhbHVlImAKF01peGVkUmVndWxhckFuZE9wdGlvbmFsEhUK",
"DXJlZ3VsYXJfZmllbGQYASABKAkSGwoOb3B0aW9uYWxfZmllbGQYAiABKAlI",
"AIgBAUIRCg9fb3B0aW9uYWxfZmllbGQiOQoST25lb2ZXaXRoTm9uZUZpZWxk",
"EgsKAXgYASABKAlIABIOCgRub25lGAIgASgJSABCBgoEdGVzdCI1ChFPbmVv",
"ZldpdGhOb25lTmFtZRILCgF4GAEgASgJSAASCwoBeRgCIAEoCUgAQgYKBG5v",
"bmUikwIKGURpc2FtYmlndWF0ZUNvbW1vbk1lbWJlcnMSIwobZGlzYW1iaWd1",
"YXRlX2NvbW1vbl9tZW1iZXJzGAEgASgFEg0KBXR5cGVzGAIgASgFEhIKCmRl",
"c2NyaXB0b3IYAyABKAUSDgoGZXF1YWxzGAQgASgFEhEKCXRvX3N0cmluZxgF",
"IAEoBRIVCg1nZXRfaGFzaF9jb2RlGAYgASgFEhAKCHdyaXRlX3RvGAcgASgF",
"Eg0KBWNsb25lGAggASgFEhYKDmNhbGN1bGF0ZV9zaXplGAkgASgFEhIKCm1l",
"cmdlX2Zyb20YCiABKAUSFwoPb25fY29uc3RydWN0aW9uGAsgASgFEg4KBnBh",
"cnNlchgMIAEoBSpVCgxOZWdhdGl2ZUVudW0SFgoSTkVHQVRJVkVfRU5VTV9a",
"RVJPEAASFgoJRml2ZUJlbG93EPv//////////wESFQoITWludXNPbmUQ////",
"////////ASo2Cg5EZXByZWNhdGVkRW51bRIXCg9ERVBSRUNBVEVEX1pFUk8Q",
"ABoCCAESBwoDb25lEAEaAhgBQh2qAhpVbml0VGVzdC5Jc3N1ZXMuVGVzdFBy",
"b3Rvc2IGcHJvdG8z"));
descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
new pbr::FileDescriptor[] { global::Google.Protobuf.WellKnownTypes.StructReflection.Descriptor, },
new pbr::GeneratedClrTypeInfo(new[] {typeof(global::UnitTest.Issues.TestProtos.NegativeEnum), typeof(global::UnitTest.Issues.TestProtos.DeprecatedEnum), }, null, new pbr::GeneratedClrTypeInfo[] {
@ -97,7 +98,9 @@ namespace UnitTest.Issues.TestProtos {
[pbr::OriginalName("MinusOne")] MinusOne = -1,
}
[global::System.ObsoleteAttribute]
public enum DeprecatedEnum {
[global::System.ObsoleteAttribute]
[pbr::OriginalName("DEPRECATED_ZERO")] DeprecatedZero = 0,
[pbr::OriginalName("one")] One = 1,
}
@ -826,6 +829,7 @@ namespace UnitTest.Issues.TestProtos {
}
[global::System.ObsoleteAttribute]
public sealed partial class DeprecatedChild : pb::IMessage<DeprecatedChild>
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
, pb::IBufferMessage

@ -888,5 +888,17 @@ namespace Google.Protobuf.Collections
Assert.DoesNotThrow(() => list.Capacity = 0, "Can set Capacity to 0");
Assert.AreEqual(0, list.Capacity);
}
[Test]
public void Clear_CapacityUnaffected()
{
var list = new RepeatedField<int> { 1 };
Assert.AreEqual(1, list.Count);
Assert.AreEqual(8, list.Capacity);
list.Clear();
Assert.AreEqual(0, list.Count);
Assert.AreEqual(8, list.Capacity);
}
}
}

@ -34,7 +34,9 @@ using System;
using System.Reflection;
using Google.Protobuf.TestProtos;
using NUnit.Framework;
using UnitTest.Issues.TestProtos;
#pragma warning disable CS0612 // Type or member is obsolete
namespace Google.Protobuf
{
public class DeprecatedMemberTest
@ -46,9 +48,20 @@ namespace Google.Protobuf
}
[Test]
public void TestDepreatedPrimitiveValue()
{
AssertIsDeprecated(typeof(TestDeprecatedFields).GetProperty("DeprecatedInt32"));
}
public void TestDepreatedPrimitiveValue() =>
AssertIsDeprecated(typeof(TestDeprecatedFields).GetProperty(nameof(TestDeprecatedFields.DeprecatedInt32)));
[Test]
public void TestDeprecatedMessage() =>
AssertIsDeprecated(typeof(DeprecatedChild));
[Test]
public void TestDeprecatedEnum() =>
AssertIsDeprecated(typeof(DeprecatedEnum));
[Test]
public void TestDeprecatedEnumValue() =>
AssertIsDeprecated(typeof(DeprecatedEnum).GetField(nameof(DeprecatedEnum.DeprecatedZero)));
}
}
#pragma warning restore CS0612 // Type or member is obsolete

@ -128,5 +128,38 @@ namespace Google.Protobuf.WellKnownTypes
var duration = new Duration { Seconds = 1, Nanos = -1 };
Assert.AreEqual("{ \"@warning\": \"Invalid Duration\", \"seconds\": \"1\", \"nanos\": -1 }", duration.ToString());
}
[Test]
public void Comparability()
{
Duration[] durationsInExpectedSortOrder =
{
null,
new Duration { Seconds = -10, Nanos = -10 },
new Duration { Seconds = -10, Nanos = -1 },
new Duration { Seconds = -1, Nanos = -10 },
new Duration { Seconds = -1, Nanos = -1 },
new Duration(),
new Duration { Seconds = 1, Nanos = 1 },
new Duration { Seconds = 1, Nanos = 10 },
new Duration { Seconds = 10, Nanos = 1 },
new Duration { Seconds = 10, Nanos = 10 }
};
for (int i = 0; i < durationsInExpectedSortOrder.Length; i++)
{
var target = durationsInExpectedSortOrder[i];
if (target is null)
{
continue;
}
for (int j = 0; j < durationsInExpectedSortOrder.Length; j++)
{
var expectedResult = Math.Sign(i - j);
var actualResult = target.CompareTo(durationsInExpectedSortOrder[j]);
Assert.AreEqual(expectedResult, actualResult);
}
}
}
}
}

@ -12,8 +12,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Google.Protobuf.Conformance
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Google.Protobuf.JsonDump", "Google.Protobuf.JsonDump\Google.Protobuf.JsonDump.csproj", "{9695E08F-9829-497D-B95C-B38F28D48690}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Google.Protobuf.Benchmarks", "Google.Protobuf.Benchmarks\Google.Protobuf.Benchmarks.csproj", "{D25E4804-4DEA-45AB-9F8C-BA4DBD8E5A07}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Google.Protobuf.Test.TestProtos", "Google.Protobuf.Test.TestProtos\Google.Protobuf.Test.TestProtos.csproj", "{ADF24BEB-A318-4530-8448-356B72B820EA}"
EndProject
Global
@ -42,10 +40,6 @@ Global
{9695E08F-9829-497D-B95C-B38F28D48690}.Debug|Any CPU.Build.0 = Debug|Any CPU
{9695E08F-9829-497D-B95C-B38F28D48690}.Release|Any CPU.ActiveCfg = Release|Any CPU
{9695E08F-9829-497D-B95C-B38F28D48690}.Release|Any CPU.Build.0 = Release|Any CPU
{D25E4804-4DEA-45AB-9F8C-BA4DBD8E5A07}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D25E4804-4DEA-45AB-9F8C-BA4DBD8E5A07}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D25E4804-4DEA-45AB-9F8C-BA4DBD8E5A07}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D25E4804-4DEA-45AB-9F8C-BA4DBD8E5A07}.Release|Any CPU.Build.0 = Release|Any CPU
{ADF24BEB-A318-4530-8448-356B72B820EA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{ADF24BEB-A318-4530-8448-356B72B820EA}.Debug|Any CPU.Build.0 = Debug|Any CPU
{ADF24BEB-A318-4530-8448-356B72B820EA}.Release|Any CPU.ActiveCfg = Release|Any CPU

@ -279,8 +279,9 @@ namespace Google.Protobuf.Collections
}
/// <summary>
/// Gets and sets the capacity of the RepeatedField's internal array. WHen set, the internal array is reallocated to the given capacity.
/// <exception cref="ArgumentOutOfRangeException">The new value is less than Count -or- when Count is less than 0.</exception>
/// Gets and sets the capacity of the RepeatedField's internal array.
/// When set, the internal array is reallocated to the given capacity.
/// <exception cref="ArgumentOutOfRangeException">The new value is less than <see cref="Count"/>.</exception>
/// </summary>
public int Capacity
{
@ -338,7 +339,10 @@ namespace Google.Protobuf.Collections
/// </summary>
public void Clear()
{
array = EmptyArray;
// Clear the content of the array (so that any objects it referred to can be garbage collected)
// but keep the capacity the same. This allows large repeated fields to be reused without
// array reallocation.
Array.Clear(array, 0, count);
count = 0;
}

@ -47,10 +47,3 @@ using System.Security;
"981207041fd5b2da3b498346fcfcd94910d52f25537c4a43ce3fbe17dc7d43e6cbdb4d8f1242dc" +
"b6bd9b5906be74da8daa7d7280f97130f318a16c07baf118839b156299a48522f9fae2371c9665" +
"c5ae9cb6")]
[assembly: InternalsVisibleTo("Google.Protobuf.Benchmarks, PublicKey=" +
"002400000480000094000000060200000024000052534131000400000100010025800fbcfc63a1" +
"7c66b303aae80b03a6beaa176bb6bef883be436f2a1579edd80ce23edf151a1f4ced97af83abcd" +
"981207041fd5b2da3b498346fcfcd94910d52f25537c4a43ce3fbe17dc7d43e6cbdb4d8f1242dc" +
"b6bd9b5906be74da8daa7d7280f97130f318a16c07baf118839b156299a48522f9fae2371c9665" +
"c5ae9cb6")]

@ -38,7 +38,7 @@ namespace Google.Protobuf.WellKnownTypes
{
// Manually-written partial class for the Duration well-known type,
// providing a conversion to TimeSpan and convenience operators.
public partial class Duration : ICustomDiagnosticMessage
public partial class Duration : ICustomDiagnosticMessage, IComparable<Duration>
{
/// <summary>
/// The number of nanoseconds in a second.
@ -266,5 +266,26 @@ namespace Google.Protobuf.WellKnownTypes
}
}
}
/// <summary>
/// Given another duration, returns 0 if the durations are equivalent, -1 if this duration is shorter than the other, and 1 otherwise.
/// </summary>
/// <remarks>
/// This method expects that both durations are normalized; that is, that the values of <see cref="Seconds"/>
/// and <see cref="Nanos"/> are within the documented bounds.
/// If either value is not normalized, the results of this method are unspecified.
/// </remarks>
/// <param name="other">The duration to compare with this object.</param>
/// <returns>An integer indicating whether this duration is shorter or longer than <paramref name="other"/>.</returns>
public int CompareTo(Duration other)
{
return other == null ? 1
: Seconds < other.Seconds ? -1
: Seconds > other.Seconds ? 1
: Nanos < other.Nanos ? -1
: Nanos > other.Nanos ? 1
: 0;
}
}
}

@ -1,304 +0,0 @@
# Protobuf Performance
The following benchmark test results were produced on a workstation utilizing an Intel® Xeon® Processor E5-2630 with 32GB of RAM.
This table contains the results of three separate languages:
* **C++** - For C++, there are three parsing methods:
* **new** - This is for using a new operator for creating a message instance.
* **new arena** - This is for using arena for creating a new message instance.
* **reuse** - This is for reusing the same message instance for parsing.
* **Java** - For Java, there are three parsing/serialization methods:
* **byte[]** - This is for parsing from a Byte Array.
* **ByteString** - This is for parsing from a
com.google.protobuf.ByteString.
* **InputStream** - This is for parsing from an InputStream.
* **Python** - For Python, there are three types of Python protobuf for testing:
* **C++-generated-code** - This is for using C++ generated code of the
proto file as a dynamic linked library.
* **C++-reflection** - This is for using C++ reflection, for which there's no
generated code, but still using C++ protobuf library as a dynamic linked
library.
* **pure-Python** - This is for the pure version of Python, which does not link with
any C++ protobuf library.
## Parsing performance
<table>
<tbody><tr>
<th rowspan="2"> </th>
<th colspan="3" rowspan="1">C++</th>
<th colspan="3" rowspan="1">C++ with tcmalloc</th>
<th colspan="3" rowspan="1">java</th>
<th colspan="3" rowspan="1">python</th>
</tr>
<tr>
<th colspan="1">new</th>
<th colspan="1">new arena</th>
<th colspan="1">reuse</th>
<th colspan="1">new</th>
<th colspan="1">new arena</th>
<th colspan="1">reuse</th>
<th colspan="1">byte[]</th>
<th colspan="1">ByteString</th>
<th colspan="1">InputStream</th>
<th colspan="1">C++-generated-code</th>
<th colspan="1">C++-reflection</th>
<th colspan="1">pure-Python</th>
</tr>
<tr>
<td>google_message1_proto2</td>
<td>368.717MB/s</td>
<td>261.847MB/s</td>
<td>799.403MB/s</td>
<td>645.183MB/s</td>
<td>441.023MB/s</td>
<td>1.122GB/s</td>
<td>425.437MB/s</td>
<td>425.937MB/s</td>
<td>251.018MB/s</td>
<td>82.8314MB/s</td>
<td>47.6763MB/s</td>
<td>3.76299MB/s</td>
</tr>
<tr>
<td>google_message1_proto3</td>
<td>294.517MB/s</td>
<td>229.116MB/s</td>
<td>469.982MB/s</td>
<td>434.510MB/s</td>
<td>394.701MB/s</td>
<td>591.931MB/s</td>
<td>357.597MB/s</td>
<td>378.568MB/s</td>
<td>221.676MB/s</td>
<td>82.0498MB/s</td>
<td>39.9467MB/s</td>
<td>3.77751MB/s</td>
</tr>
<tr>
<td>google_message2</td>
<td>277.242MB/s</td>
<td>347.611MB/s</td>
<td>793.67MB/s</td>
<td>503.721MB/s</td>
<td>596.333MB/s</td>
<td>922.533MB/s</td>
<td>416.778MB/s</td>
<td>419.543MB/s</td>
<td>367.145MB/s</td>
<td>241.46MB/s</td>
<td>71.5723MB/s</td>
<td>2.73538MB/s</td>
</tr>
<tr>
<td>google_message3_1</td>
<td>213.478MB/s</td>
<td>291.58MB/s</td>
<td>543.398MB/s</td>
<td>539.704MB/s</td>
<td>717.300MB/s</td>
<td>927.333MB/s</td>
<td>684.241MB/s</td>
<td>704.47MB/s</td>
<td>648.624MB/s</td>
<td>209.036MB/s</td>
<td>142.356MB/s</td>
<td>15.3324MB/s</td>
</tr>
<tr>
<td>google_message3_2</td>
<td>672.685MB/s</td>
<td>802.767MB/s</td>
<td>1.21505GB/s</td>
<td>985.790MB/s</td>
<td>1.136GB/s</td>
<td>1.367GB/s</td>
<td>1.54439GB/s</td>
<td>1.60603GB/s</td>
<td>1.33443GB/s</td>
<td>573.835MB/s</td>
<td>314.33MB/s</td>
<td>15.0169MB/s</td>
</tr>
<tr>
<td>google_message3_3</td>
<td>207.681MB/s</td>
<td>140.591MB/s</td>
<td>535.181MB/s</td>
<td>369.743MB/s</td>
<td>262.301MB/s</td>
<td>556.644MB/s</td>
<td>279.385MB/s</td>
<td>304.853MB/s</td>
<td>107.575MB/s</td>
<td>32.248MB/s</td>
<td>26.1431MB/s</td>
<td>2.63541MB/s</td>
</tr>
<tr>
<td>google_message3_4</td>
<td>7.96091GB/s</td>
<td>7.10024GB/s</td>
<td>9.3013GB/s</td>
<td>8.518GB/s</td>
<td>8.171GB/s</td>
<td>9.917GB/s</td>
<td>5.78006GB/s</td>
<td>5.85198GB/s</td>
<td>4.62609GB/s</td>
<td>2.49631GB/s</td>
<td>2.35442GB/s</td>
<td>802.061MB/s</td>
</tr>
<tr>
<td>google_message3_5</td>
<td>76.0072MB/s</td>
<td>51.6769MB/s</td>
<td>237.856MB/s</td>
<td>178.495MB/s</td>
<td>111.751MB/s</td>
<td>329.569MB/s</td>
<td>121.038MB/s</td>
<td>132.866MB/s</td>
<td>36.9197MB/s</td>
<td>10.3962MB/s</td>
<td>8.84659MB/s</td>
<td>1.25203MB/s</td>
</tr>
<tr>
<td>google_message4</td>
<td>331.46MB/s</td>
<td>404.862MB/s</td>
<td>427.99MB/s</td>
<td>589.887MB/s</td>
<td>720.367MB/s</td>
<td>705.373MB/s</td>
<td>606.228MB/s</td>
<td>589.13MB/s</td>
<td>530.692MB/s</td>
<td>305.543MB/s</td>
<td>174.834MB/s</td>
<td>7.86485MB/s</td>
</tr>
</tbody></table>
## Serialization performance
<table>
<tbody><tr>
<th rowspan="2"> </th>
<th colspan="1" rowspan="2">C++</th>
<th colspan="1" rowspan="2">C++ with tcmalloc</th>
<th colspan="3" rowspan="1">java</th>
<th colspan="3" rowspan="1">python</th>
</tr>
<tr>
<th colspan="1">byte[]</th>
<th colspan="1">ByteString</th>
<th colspan="1">InputStream</th>
<th colspan="1">C++-generated-code</th>
<th colspan="1">C++-reflection</th>
<th colspan="1">pure-Python</th>
</tr>
<tr>
<td>google_message1_proto2</td>
<td>1.39698GB/s</td>
<td>1.701GB/s</td>
<td>1.12915GB/s</td>
<td>1.13589GB/s</td>
<td>758.609MB/s</td>
<td>260.911MB/s</td>
<td>58.4815MB/s</td>
<td>5.77824MB/s</td>
</tr>
<tr>
<td>google_message1_proto3</td>
<td>959.305MB/s</td>
<td>939.404MB/s</td>
<td>1.15372GB/s</td>
<td>1.07824GB/s</td>
<td>802.337MB/s</td>
<td>239.4MB/s</td>
<td>33.6336MB/s</td>
<td>5.80524MB/s</td>
</tr>
<tr>
<td>google_message2</td>
<td>1.27429GB/s</td>
<td>1.402GB/s</td>
<td>1.01039GB/s</td>
<td>1022.99MB/s</td>
<td>798.736MB/s</td>
<td>996.755MB/s</td>
<td>57.9601MB/s</td>
<td>4.09246MB/s</td>
</tr>
<tr>
<td>google_message3_1</td>
<td>1.31916GB/s</td>
<td>2.049GB/s</td>
<td>991.496MB/s</td>
<td>860.332MB/s</td>
<td>662.88MB/s</td>
<td>1.48625GB/s</td>
<td>421.287MB/s</td>
<td>18.002MB/s</td>
</tr>
<tr>
<td>google_message3_2</td>
<td>2.15676GB/s</td>
<td>2.632GB/s</td>
<td>2.14736GB/s</td>
<td>2.08136GB/s</td>
<td>1.55997GB/s</td>
<td>2.39597GB/s</td>
<td>326.777MB/s</td>
<td>16.0527MB/s</td>
</tr>
<tr>
<td>google_message3_3</td>
<td>650.456MB/s</td>
<td>1.040GB/s</td>
<td>593.52MB/s</td>
<td>580.667MB/s</td>
<td>346.839MB/s</td>
<td>123.978MB/s</td>
<td>35.893MB/s</td>
<td>2.32834MB/s</td>
</tr>
<tr>
<td>google_message3_4</td>
<td>8.70154GB/s</td>
<td>9.825GB/s</td>
<td>5.88645GB/s</td>
<td>5.93946GB/s</td>
<td>2.44388GB/s</td>
<td>5.9241GB/s</td>
<td>4.05837GB/s</td>
<td>876.87MB/s</td>
</tr>
<tr>
<td>google_message3_5</td>
<td>246.33MB/s</td>
<td>443.993MB/s</td>
<td>283.278MB/s</td>
<td>259.167MB/s</td>
<td>206.37MB/s</td>
<td>37.0285MB/s</td>
<td>12.2228MB/s</td>
<td>1.1979MB/s</td>
</tr>
<tr>
<td>google_message4</td>
<td>1.56674GB/s</td>
<td>2.19601GB/s</td>
<td>776.907MB/s</td>
<td>770.707MB/s</td>
<td>702.931MB/s</td>
<td>1.49623GB/s</td>
<td>205.116MB/s</td>
<td>8.93428MB/s</td>
</tr>
</tbody></table>
\* The cpp performance can be improved by using [tcmalloc](https://gperftools.github.io/gperftools/tcmalloc.html), please follow the (instruction)[https://github.com/protocolbuffers/protobuf/blob/main/benchmarks/README.md] to link with tcmalloc to get the faster result.

@ -37,7 +37,7 @@ minimum requirement is to install protocol compiler (i.e., the protoc binary)
and the protobuf runtime for the language you want to build.
You can simply run "make" to build the example for all languages (except for
Go). However, since different language has different installation requirement,
Go). However, since different languages have different installation requirements,
it will likely fail. It's better to follow individual instructions below to
build only the language you are interested in.

@ -1,11 +0,0 @@
# Config file for running tests in Kokoro
# Location of the build script in repository
build_file: "protobuf/kokoro/linux/benchmark/run.sh"
timeout_mins: 240
action {
define_artifacts {
regex: "**/sponge_log.xml"
}
}

@ -1,66 +0,0 @@
#!/bin/bash
#
# Install Bazel 4.2.2.
use_bazel.sh 4.2.2
# Change to repo root
cd $(dirname $0)/../../..
SCRIPT_ROOT=$(pwd)
set -ex
export OUTPUT_DIR=testoutput
repo_root="$(pwd)"
# Setup python environment.
pyenv install -v 3.9.5 -s
pyenv global 3.9.5
pyenv versions
python --version
python -m venv "venv"
source "venv/bin/activate"
# TODO(jtattermusch): Add back support for benchmarking with tcmalloc for C++ and python.
# This feature was removed since it used to use tcmalloc from https://github.com/gperftools/gperftools.git
# which is very outdated. See https://github.com/protocolbuffers/protobuf/issues/8725.
# download datasets for benchmark
pushd benchmarks
datasets=$(for file in $(find . -type f -name "dataset.*.pb" -not -path "./tmp/*"); do echo "$(pwd)/$file"; done | xargs)
echo $datasets
popd
# build and run Python benchmark
echo "benchmarking pure python..."
${SCRIPT_ROOT}/kokoro/common/bazel_wrapper.sh run //benchmarks/python:python_benchmark -- \
--json --behavior_prefix="pure-python-benchmark" $datasets > /tmp/python1.json
echo "benchmarking python cpp reflection..."
${SCRIPT_ROOT}/kokoro/common/bazel_wrapper.sh run //benchmarks/python:python_benchmark --define=use_fast_cpp_protos=true -- \
--json --behavior_prefix="cpp-reflection-benchmark" $datasets > /tmp/python2.json
echo "benchmarking python cpp generated code..."
${SCRIPT_ROOT}/kokoro/common/bazel_wrapper.sh run //benchmarks/python:python_benchmark --define=use_fast_cpp_protos=true -- \
--json --cpp_generated --behavior_prefix="cpp-generated-code-benchmark" $datasets >> /tmp/python3.json
jq -s . /tmp/python1.json /tmp/python2.json /tmp/python3.json > python_result.json
# build and run C++ benchmark
echo "benchmarking cpp..."
${SCRIPT_ROOT}/kokoro/common/bazel_wrapper.sh run //benchmarks/cpp:cpp_benchmark -- \
--benchmark_min_time=5.0 --benchmark_out_format=json --benchmark_out="${repo_root}/cpp_result.json" $datasets
# build and run java benchmark (java 11 is required)
echo "benchmarking java..."
${SCRIPT_ROOT}/kokoro/common/bazel_wrapper.sh run //benchmarks/java:java_benchmark -- \
-Cresults.file.options.file="${repo_root}/java_result.json" $datasets
# persist raw the results in the build job log (for better debuggability)
cat cpp_result.json
cat java_result.json
cat python_result.json
# print the postprocessed results to the build job log
# TODO(jtattermusch): re-enable uploading results to bigquery (it is currently broken)
bazel run //benchmarks/util:result_parser -- \
-cpp="${repo_root}/cpp_result.json" \
-java="${repo_root}/java_result.json" \
-python="${repo_root}/python_result.json"

@ -9,10 +9,11 @@ cd $(dirname $0)/../../..
source kokoro/macos/prepare_build_macos_rc
# Install Dependencies
brew cleanup
brew install coreutils php@7.4
# Configure path
PHP_FOLDER=$(find $HOMEBREW_PREFIX -type d -regex ".*php.*/7.4.[0-9]*")
PHP_FOLDER=$(find $HOMEBREW_PREFIX -type d -regex ".*php.*/7.4.[0-9_.]*" | sort -n | tail -n 1)
test ! -z "$PHP_FOLDER"
export PATH="$PHP_FOLDER/bin:$PATH"

@ -9,10 +9,11 @@ cd $(dirname $0)/../../..
source kokoro/macos/prepare_build_macos_rc
# Install Dependencies
brew cleanup
brew install coreutils php@8.0
# Configure path
PHP_FOLDER=$(find $HOMEBREW_PREFIX -type d -regex ".*php.*/8.0.[0-9]*")
PHP_FOLDER=$(find $HOMEBREW_PREFIX -type d -regex ".*php.*/8.0.[0-9_.]*" | sort -n | tail -n 1)
test ! -z "$PHP_FOLDER"
export PATH="$PHP_FOLDER/bin:$PATH"

@ -1,10 +1,13 @@
set PATH=C:\Program Files (x86)\MSBuild\14.0\bin\;%PATH%
set generator32=Visual Studio 15
set generator64=Visual Studio 15 Win64
set vcplatform32=win32
set vcplatform64=x64
set configuration=Release
:: VS2017 is installed, but will not be selected by default. This command sets
:: up the environment so that CMake will find and use it:
call "%ProgramFiles(x86)%\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build\vcvarsall.bat" x64
echo Building protoc
cd github\protobuf

@ -42,10 +42,8 @@ OBJC_TEST_PROTO_FILES=(
objectivec/Tests/unittest_extension_chain_e.proto
objectivec/Tests/unittest_extension_chain_f.proto
objectivec/Tests/unittest_extension_chain_g.proto
objectivec/Tests/unittest_import_public_lite.proto
objectivec/Tests/unittest_import_public.proto
objectivec/Tests/unittest_import.proto
objectivec/Tests/unittest_mset_wire_format.proto
objectivec/Tests/unittest_mset.proto
objectivec/Tests/unittest_objc_options.proto
objectivec/Tests/unittest_objc_startup.proto
@ -128,8 +126,11 @@ find "${OUTPUT_DIR}" \
# -----------------------------------------------------------------------------
# Generate the Objective C specific testing protos.
"${PROTOC}" \
--objc_out="${OUTPUT_DIR}" \
--proto_path=. \
--proto_path=src \
"${PROTOC}" \
--objc_out="${OUTPUT_DIR}" \
--objc_opt=expected_prefixes_path=objectivec/Tests/expected_prefixes.txt \
--objc_opt=prefixes_must_be_registered=yes \
--objc_opt=require_prefixes=yes \
--proto_path=. \
--proto_path=src \
"${OBJC_TEST_PROTO_FILES[@]}"

@ -26,7 +26,7 @@
8B8B615D17DF7056002EE618 /* GPBARCUnittestProtos.m in Sources */ = {isa = PBXBuildFile; fileRef = 8B8B615C17DF7056002EE618 /* GPBARCUnittestProtos.m */; settings = {COMPILER_FLAGS = "-fobjc-arc"; }; };
8B96157414C8C38C00A2AC0B /* GPBDescriptor.m in Sources */ = {isa = PBXBuildFile; fileRef = 8B96157314C8C38C00A2AC0B /* GPBDescriptor.m */; };
8BBEA4A9147C727D00C4ADB7 /* GPBCodedInputStreamTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 7461B69B0F94FDF800A0C422 /* GPBCodedInputStreamTests.m */; };
8BBEA4AA147C727D00C4ADB7 /* GPBCodedOuputStreamTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 7461B69D0F94FDF800A0C422 /* GPBCodedOuputStreamTests.m */; };
8BBEA4AA147C727D00C4ADB7 /* GPBCodedOutputStreamTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 7461B69D0F94FDF800A0C422 /* GPBCodedOutputStreamTests.m */; };
8BBEA4AC147C727D00C4ADB7 /* GPBMessageTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 7461B6A30F94FDF800A0C422 /* GPBMessageTests.m */; };
8BBEA4B0147C727D00C4ADB7 /* GPBTestUtilities.m in Sources */ = {isa = PBXBuildFile; fileRef = 7461B6AC0F94FDF800A0C422 /* GPBTestUtilities.m */; };
8BBEA4B6147C727D00C4ADB7 /* GPBUnknownFieldSetTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 7461B6B80F94FDF900A0C422 /* GPBUnknownFieldSetTest.m */; };
@ -139,7 +139,7 @@
7461B4E80F94F99000A0C422 /* GPBWireFormat.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GPBWireFormat.m; sourceTree = "<group>"; };
7461B52E0F94FAF800A0C422 /* libProtocolBuffers.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libProtocolBuffers.a; sourceTree = BUILT_PRODUCTS_DIR; };
7461B69B0F94FDF800A0C422 /* GPBCodedInputStreamTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GPBCodedInputStreamTests.m; sourceTree = "<group>"; };
7461B69D0F94FDF800A0C422 /* GPBCodedOuputStreamTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GPBCodedOuputStreamTests.m; sourceTree = "<group>"; };
7461B69D0F94FDF800A0C422 /* GPBCodedOutputStreamTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GPBCodedOutputStreamTests.m; sourceTree = "<group>"; };
7461B6A30F94FDF800A0C422 /* GPBMessageTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GPBMessageTests.m; sourceTree = "<group>"; };
7461B6AB0F94FDF800A0C422 /* GPBTestUtilities.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GPBTestUtilities.h; sourceTree = "<group>"; };
7461B6AC0F94FDF800A0C422 /* GPBTestUtilities.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GPBTestUtilities.m; sourceTree = "<group>"; };
@ -218,9 +218,7 @@
F44FEABE28B5465900EC57B3 /* unittest_deprecated_file.proto */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.protobuf; path = unittest_deprecated_file.proto; sourceTree = "<group>"; };
F44FEABF28B5465900EC57B3 /* unittest_mset.proto */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.protobuf; path = unittest_mset.proto; sourceTree = "<group>"; };
F44FEAC028B5465900EC57B3 /* unittest_import.proto */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.protobuf; path = unittest_import.proto; sourceTree = "<group>"; };
F44FEAC128B5465900EC57B3 /* unittest_mset_wire_format.proto */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.protobuf; path = unittest_mset_wire_format.proto; sourceTree = "<group>"; };
F44FEAC228B5465900EC57B3 /* unittest.proto */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.protobuf; path = unittest.proto; sourceTree = "<group>"; };
F44FEAC328B5465900EC57B3 /* unittest_import_public_lite.proto */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.protobuf; path = unittest_import_public_lite.proto; sourceTree = "<group>"; };
F44FEAC428B5465900EC57B3 /* unittest_preserve_unknown_enum.proto */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.protobuf; path = unittest_preserve_unknown_enum.proto; sourceTree = "<group>"; };
F44FEAC528B5465900EC57B3 /* any_test.proto */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.protobuf; path = any_test.proto; sourceTree = "<group>"; };
F44FEAC628B5465900EC57B3 /* unittest_import_public.proto */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.protobuf; path = unittest_import_public.proto; sourceTree = "<group>"; };
@ -453,7 +451,7 @@
8B8B615C17DF7056002EE618 /* GPBARCUnittestProtos.m */,
F401DC321A8E5C0200FCC765 /* GPBArrayTests.m */,
7461B69B0F94FDF800A0C422 /* GPBCodedInputStreamTests.m */,
7461B69D0F94FDF800A0C422 /* GPBCodedOuputStreamTests.m */,
7461B69D0F94FDF800A0C422 /* GPBCodedOutputStreamTests.m */,
F40EE488206BF8B00071091A /* GPBCompileTest01.m */,
F40EE481206BF8AE0071091A /* GPBCompileTest02.m */,
F40EE491206BF8B10071091A /* GPBCompileTest03.m */,
@ -519,10 +517,8 @@
F44FEAC928B5465900EC57B3 /* unittest_extension_chain_e.proto */,
F44FEAD028B5465A00EC57B3 /* unittest_extension_chain_f.proto */,
F44FEAC828B5465900EC57B3 /* unittest_extension_chain_g.proto */,
F44FEAC328B5465900EC57B3 /* unittest_import_public_lite.proto */,
F44FEAC628B5465900EC57B3 /* unittest_import_public.proto */,
F44FEAC028B5465900EC57B3 /* unittest_import.proto */,
F44FEAC128B5465900EC57B3 /* unittest_mset_wire_format.proto */,
F44FEABF28B5465900EC57B3 /* unittest_mset.proto */,
8B35468421A616F6000BD30D /* unittest_objc_options.proto */,
F4CF31701B162ED800BD9B06 /* unittest_objc_startup.proto */,
@ -764,7 +760,7 @@
F40EE4B2206BF8B90071091A /* GPBCompileTest08.m in Sources */,
F40EE4BB206BF8B90071091A /* GPBCompileTest17.m in Sources */,
F4353D391AC06F10005A6198 /* GPBDictionaryTests+UInt64.m in Sources */,
8BBEA4AA147C727D00C4ADB7 /* GPBCodedOuputStreamTests.m in Sources */,
8BBEA4AA147C727D00C4ADB7 /* GPBCodedOutputStreamTests.m in Sources */,
F40EE4C1206BF8B90071091A /* GPBCompileTest23.m in Sources */,
8BBEA4AC147C727D00C4ADB7 /* GPBMessageTests.m in Sources */,
F4B51B1E1BBC610700744318 /* GPBObjectiveCPlusPlusTest.mm in Sources */,

@ -27,7 +27,7 @@
8B96157414C8C38C00A2AC0B /* GPBDescriptor.m in Sources */ = {isa = PBXBuildFile; fileRef = 8B96157314C8C38C00A2AC0B /* GPBDescriptor.m */; };
8B9A5EEC18330A0F00A9D33B /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8B9A5E9F1831913D00A9D33B /* UIKit.framework */; };
8BBEA4A9147C727D00C4ADB7 /* GPBCodedInputStreamTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 7461B69B0F94FDF800A0C422 /* GPBCodedInputStreamTests.m */; };
8BBEA4AA147C727D00C4ADB7 /* GPBCodedOuputStreamTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 7461B69D0F94FDF800A0C422 /* GPBCodedOuputStreamTests.m */; };
8BBEA4AA147C727D00C4ADB7 /* GPBCodedOutputStreamTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 7461B69D0F94FDF800A0C422 /* GPBCodedOutputStreamTests.m */; };
8BBEA4AC147C727D00C4ADB7 /* GPBMessageTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 7461B6A30F94FDF800A0C422 /* GPBMessageTests.m */; };
8BBEA4B0147C727D00C4ADB7 /* GPBTestUtilities.m in Sources */ = {isa = PBXBuildFile; fileRef = 7461B6AC0F94FDF800A0C422 /* GPBTestUtilities.m */; };
8BBEA4B6147C727D00C4ADB7 /* GPBUnknownFieldSetTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 7461B6B80F94FDF900A0C422 /* GPBUnknownFieldSetTest.m */; };
@ -140,7 +140,7 @@
7461B4E80F94F99000A0C422 /* GPBWireFormat.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GPBWireFormat.m; sourceTree = "<group>"; };
7461B52E0F94FAF800A0C422 /* libProtocolBuffers.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libProtocolBuffers.a; sourceTree = BUILT_PRODUCTS_DIR; };
7461B69B0F94FDF800A0C422 /* GPBCodedInputStreamTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GPBCodedInputStreamTests.m; sourceTree = "<group>"; };
7461B69D0F94FDF800A0C422 /* GPBCodedOuputStreamTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GPBCodedOuputStreamTests.m; sourceTree = "<group>"; };
7461B69D0F94FDF800A0C422 /* GPBCodedOutputStreamTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GPBCodedOutputStreamTests.m; sourceTree = "<group>"; };
7461B6A30F94FDF800A0C422 /* GPBMessageTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GPBMessageTests.m; sourceTree = "<group>"; };
7461B6AB0F94FDF800A0C422 /* GPBTestUtilities.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GPBTestUtilities.h; sourceTree = "<group>"; };
7461B6AC0F94FDF800A0C422 /* GPBTestUtilities.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GPBTestUtilities.m; sourceTree = "<group>"; };
@ -226,8 +226,6 @@
F44FEAD628B546E300EC57B3 /* unittest_deprecated.proto */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.protobuf; path = unittest_deprecated.proto; sourceTree = "<group>"; };
F44FEAD728B546E300EC57B3 /* any_test.proto */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.protobuf; path = any_test.proto; sourceTree = "<group>"; };
F44FEAD828B546E300EC57B3 /* unittest_extension_chain_b.proto */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.protobuf; path = unittest_extension_chain_b.proto; sourceTree = "<group>"; };
F44FEAD928B546E300EC57B3 /* unittest_import_public_lite.proto */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.protobuf; path = unittest_import_public_lite.proto; sourceTree = "<group>"; };
F44FEADA28B546E300EC57B3 /* unittest_mset_wire_format.proto */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.protobuf; path = unittest_mset_wire_format.proto; sourceTree = "<group>"; };
F44FEADB28B546E300EC57B3 /* unittest_import.proto */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.protobuf; path = unittest_import.proto; sourceTree = "<group>"; };
F44FEADC28B546E300EC57B3 /* unittest_mset.proto */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.protobuf; path = unittest_mset.proto; sourceTree = "<group>"; };
F44FEADD28B546E300EC57B3 /* unittest.proto */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.protobuf; path = unittest.proto; sourceTree = "<group>"; };
@ -459,7 +457,7 @@
8B8B615C17DF7056002EE618 /* GPBARCUnittestProtos.m */,
F401DC341A8E5C6F00FCC765 /* GPBArrayTests.m */,
7461B69B0F94FDF800A0C422 /* GPBCodedInputStreamTests.m */,
7461B69D0F94FDF800A0C422 /* GPBCodedOuputStreamTests.m */,
7461B69D0F94FDF800A0C422 /* GPBCodedOutputStreamTests.m */,
F40EE4CD206BF9170071091A /* GPBCompileTest01.m */,
F40EE4C6206BF9170071091A /* GPBCompileTest02.m */,
F40EE4D6206BF9190071091A /* GPBCompileTest03.m */,
@ -525,10 +523,8 @@
F44FEAE328B546E300EC57B3 /* unittest_extension_chain_e.proto */,
F44FEADE28B546E300EC57B3 /* unittest_extension_chain_f.proto */,
F44FEAE128B546E300EC57B3 /* unittest_extension_chain_g.proto */,
F44FEAD928B546E300EC57B3 /* unittest_import_public_lite.proto */,
F44FEAE028B546E300EC57B3 /* unittest_import_public.proto */,
F44FEADB28B546E300EC57B3 /* unittest_import.proto */,
F44FEADA28B546E300EC57B3 /* unittest_mset_wire_format.proto */,
F44FEADC28B546E300EC57B3 /* unittest_mset.proto */,
8B35468621A61EB2000BD30D /* unittest_objc_options.proto */,
F4CF31711B162EF500BD9B06 /* unittest_objc_startup.proto */,
@ -771,7 +767,7 @@
F40EE4F7206BF91E0071091A /* GPBCompileTest08.m in Sources */,
F40EE500206BF91E0071091A /* GPBCompileTest17.m in Sources */,
F4353D471AC06F31005A6198 /* GPBDictionaryTests+UInt64.m in Sources */,
8BBEA4AA147C727D00C4ADB7 /* GPBCodedOuputStreamTests.m in Sources */,
8BBEA4AA147C727D00C4ADB7 /* GPBCodedOutputStreamTests.m in Sources */,
F40EE506206BF91E0071091A /* GPBCompileTest23.m in Sources */,
8BBEA4AC147C727D00C4ADB7 /* GPBMessageTests.m in Sources */,
F4487C811AAF62FC00531423 /* GPBMessageTests+Serialization.m in Sources */,

@ -27,7 +27,7 @@
8B96157414C8C38C00A2AC0B /* GPBDescriptor.m in Sources */ = {isa = PBXBuildFile; fileRef = 8B96157314C8C38C00A2AC0B /* GPBDescriptor.m */; };
8B9A5EEC18330A0F00A9D33B /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8B9A5E9F1831913D00A9D33B /* UIKit.framework */; };
8BBEA4A9147C727D00C4ADB7 /* GPBCodedInputStreamTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 7461B69B0F94FDF800A0C422 /* GPBCodedInputStreamTests.m */; };
8BBEA4AA147C727D00C4ADB7 /* GPBCodedOuputStreamTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 7461B69D0F94FDF800A0C422 /* GPBCodedOuputStreamTests.m */; };
8BBEA4AA147C727D00C4ADB7 /* GPBCodedOutputStreamTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 7461B69D0F94FDF800A0C422 /* GPBCodedOutputStreamTests.m */; };
8BBEA4AC147C727D00C4ADB7 /* GPBMessageTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 7461B6A30F94FDF800A0C422 /* GPBMessageTests.m */; };
8BBEA4B0147C727D00C4ADB7 /* GPBTestUtilities.m in Sources */ = {isa = PBXBuildFile; fileRef = 7461B6AC0F94FDF800A0C422 /* GPBTestUtilities.m */; };
8BBEA4B6147C727D00C4ADB7 /* GPBUnknownFieldSetTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 7461B6B80F94FDF900A0C422 /* GPBUnknownFieldSetTest.m */; };
@ -140,7 +140,7 @@
7461B4E80F94F99000A0C422 /* GPBWireFormat.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GPBWireFormat.m; sourceTree = "<group>"; };
7461B52E0F94FAF800A0C422 /* libProtocolBuffers.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libProtocolBuffers.a; sourceTree = BUILT_PRODUCTS_DIR; };
7461B69B0F94FDF800A0C422 /* GPBCodedInputStreamTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GPBCodedInputStreamTests.m; sourceTree = "<group>"; };
7461B69D0F94FDF800A0C422 /* GPBCodedOuputStreamTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GPBCodedOuputStreamTests.m; sourceTree = "<group>"; };
7461B69D0F94FDF800A0C422 /* GPBCodedOutputStreamTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GPBCodedOutputStreamTests.m; sourceTree = "<group>"; };
7461B6A30F94FDF800A0C422 /* GPBMessageTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GPBMessageTests.m; sourceTree = "<group>"; };
7461B6AB0F94FDF800A0C422 /* GPBTestUtilities.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GPBTestUtilities.h; sourceTree = "<group>"; };
7461B6AC0F94FDF800A0C422 /* GPBTestUtilities.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GPBTestUtilities.m; sourceTree = "<group>"; };
@ -218,9 +218,7 @@
F4487C801AAF62FC00531423 /* GPBMessageTests+Serialization.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "GPBMessageTests+Serialization.m"; sourceTree = "<group>"; };
F4487C841AAF6AC500531423 /* GPBMessageTests+Merge.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "GPBMessageTests+Merge.m"; sourceTree = "<group>"; };
F44929021C866B3B00C2548A /* GPBCodedOutputStream_PackagePrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GPBCodedOutputStream_PackagePrivate.h; sourceTree = "<group>"; };
F44FEAE428B5471300EC57B3 /* unittest_import_public_lite.proto */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.protobuf; path = unittest_import_public_lite.proto; sourceTree = "<group>"; };
F44FEAE528B5471300EC57B3 /* unittest_extension_chain_a.proto */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.protobuf; path = unittest_extension_chain_a.proto; sourceTree = "<group>"; };
F44FEAE628B5471300EC57B3 /* unittest_mset_wire_format.proto */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.protobuf; path = unittest_mset_wire_format.proto; sourceTree = "<group>"; };
F44FEAE728B5471300EC57B3 /* unittest_extension_chain_c.proto */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.protobuf; path = unittest_extension_chain_c.proto; sourceTree = "<group>"; };
F44FEAE828B5471300EC57B3 /* unittest_extension_chain_g.proto */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.protobuf; path = unittest_extension_chain_g.proto; sourceTree = "<group>"; };
F44FEAE928B5471300EC57B3 /* unittest_import.proto */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.protobuf; path = unittest_import.proto; sourceTree = "<group>"; };
@ -459,7 +457,7 @@
8B8B615C17DF7056002EE618 /* GPBARCUnittestProtos.m */,
F401DC341A8E5C6F00FCC765 /* GPBArrayTests.m */,
7461B69B0F94FDF800A0C422 /* GPBCodedInputStreamTests.m */,
7461B69D0F94FDF800A0C422 /* GPBCodedOuputStreamTests.m */,
7461B69D0F94FDF800A0C422 /* GPBCodedOutputStreamTests.m */,
F40EE4CD206BF9170071091A /* GPBCompileTest01.m */,
F40EE4C6206BF9170071091A /* GPBCompileTest02.m */,
F40EE4D6206BF9190071091A /* GPBCompileTest03.m */,
@ -525,10 +523,8 @@
F44FEAF428B5471300EC57B3 /* unittest_extension_chain_e.proto */,
F44FEAEC28B5471300EC57B3 /* unittest_extension_chain_f.proto */,
F44FEAE828B5471300EC57B3 /* unittest_extension_chain_g.proto */,
F44FEAE428B5471300EC57B3 /* unittest_import_public_lite.proto */,
F44FEAEB28B5471300EC57B3 /* unittest_import_public.proto */,
F44FEAE928B5471300EC57B3 /* unittest_import.proto */,
F44FEAE628B5471300EC57B3 /* unittest_mset_wire_format.proto */,
F44FEAF128B5471300EC57B3 /* unittest_mset.proto */,
8B35468621A61EB2000BD30D /* unittest_objc_options.proto */,
F4CF31711B162EF500BD9B06 /* unittest_objc_startup.proto */,
@ -771,7 +767,7 @@
F40EE4F7206BF91E0071091A /* GPBCompileTest08.m in Sources */,
F40EE500206BF91E0071091A /* GPBCompileTest17.m in Sources */,
F4353D471AC06F31005A6198 /* GPBDictionaryTests+UInt64.m in Sources */,
8BBEA4AA147C727D00C4ADB7 /* GPBCodedOuputStreamTests.m in Sources */,
8BBEA4AA147C727D00C4ADB7 /* GPBCodedOutputStreamTests.m in Sources */,
F40EE506206BF91E0071091A /* GPBCompileTest23.m in Sources */,
8BBEA4AC147C727D00C4ADB7 /* GPBMessageTests.m in Sources */,
F4487C811AAF62FC00531423 /* GPBMessageTests+Serialization.m in Sources */,

@ -40,7 +40,6 @@
#import "objectivec/Tests/UnittestDeprecatedFile.pbobjc.h"
#import "objectivec/Tests/UnittestImport.pbobjc.h"
#import "objectivec/Tests/UnittestImportPublic.pbobjc.h"
#import "objectivec/Tests/UnittestImportPublicLite.pbobjc.h"
#import "objectivec/Tests/UnittestMset.pbobjc.h"
#import "objectivec/Tests/UnittestObjc.pbobjc.h"
#import "objectivec/Tests/UnittestObjcOptions.pbobjc.h"

@ -40,9 +40,7 @@
#import "objectivec/Tests/UnittestDeprecatedFile.pbobjc.m"
#import "objectivec/Tests/UnittestImport.pbobjc.m"
#import "objectivec/Tests/UnittestImportPublic.pbobjc.m"
#import "objectivec/Tests/UnittestImportPublicLite.pbobjc.m"
#import "objectivec/Tests/UnittestMset.pbobjc.m"
#import "objectivec/Tests/UnittestMsetWireFormat.pbobjc.m"
#import "objectivec/Tests/UnittestObjc.pbobjc.m"
#import "objectivec/Tests/UnittestObjcOptions.pbobjc.m"
#import "objectivec/Tests/UnittestObjcStartup.pbobjc.m"

@ -161,9 +161,9 @@ static const NSTimeInterval kTimeAccuracy = 1e-9;
// Set and extract covers most of the code.
TestAny *subMessage = [TestAny message];
AnyTestMessage *subMessage = [AnyTestMessage message];
subMessage.int32Value = 12345;
TestAny *message = [TestAny message];
AnyTestMessage *message = [AnyTestMessage message];
NSError *err = nil;
message.anyValue = [GPBAny anyWithMessage:subMessage error:&err];
XCTAssertNil(err);
@ -171,14 +171,14 @@ static const NSTimeInterval kTimeAccuracy = 1e-9;
NSData *data = message.data;
XCTAssertNotNil(data);
TestAny *message2 = [TestAny parseFromData:data error:&err];
AnyTestMessage *message2 = [AnyTestMessage parseFromData:data error:&err];
XCTAssertNil(err);
XCTAssertNotNil(message2);
XCTAssertTrue(message2.hasAnyValue);
TestAny *subMessage2 =
(TestAny *)[message.anyValue unpackMessageClass:[TestAny class]
error:&err];
AnyTestMessage *subMessage2 =
(AnyTestMessage *)[message.anyValue unpackMessageClass:[AnyTestMessage class]
error:&err];
XCTAssertNil(err);
XCTAssertNotNil(subMessage2);
XCTAssertEqual(subMessage2.int32Value, 12345);
@ -189,9 +189,9 @@ static const NSTimeInterval kTimeAccuracy = 1e-9;
NSData *data2 = message.data;
XCTAssertEqualObjects(data2, data);
TestAny *subMessage3 =
(TestAny *)[message.anyValue unpackMessageClass:[TestAny class]
error:NULL];
AnyTestMessage *subMessage3 =
(AnyTestMessage *)[message.anyValue unpackMessageClass:[AnyTestMessage class]
error:NULL];
XCTAssertNotNil(subMessage3);
XCTAssertEqualObjects(subMessage2, subMessage3);

@ -35,7 +35,6 @@
#import "GPBUnknownField_PackagePrivate.h"
#import "objectivec/Tests/Unittest.pbobjc.h"
#import "objectivec/Tests/UnittestMset.pbobjc.h"
#import "objectivec/Tests/UnittestMsetWireFormat.pbobjc.h"
@interface WireFormatTests : GPBTestCase
@end
@ -144,11 +143,11 @@
const int kUnknownTypeId = 1550055;
- (void)testSerializeMessageSet {
// Set up a TestMessageSet with two known messages and an unknown one.
TestMessageSet* message_set = [TestMessageSet message];
[[message_set getExtension:[TestMessageSetExtension1 messageSetExtension]]
// Set up a MSetMessage with two known messages and an unknown one.
MSetMessage* message_set = [MSetMessage message];
[[message_set getExtension:[MSetMessageExtension1 messageSetExtension]]
setI:123];
[[message_set getExtension:[TestMessageSetExtension2 messageSetExtension]]
[[message_set getExtension:[MSetMessageExtension2 messageSetExtension]]
setStr:@"foo"];
GPBUnknownField* unknownField =
[[[GPBUnknownField alloc] initWithNumber:kUnknownTypeId] autorelease];
@ -160,26 +159,26 @@ const int kUnknownTypeId = 1550055;
NSData* data = [message_set data];
// Parse back using RawMessageSet and check the contents.
RawMessageSet* raw = [RawMessageSet parseFromData:data error:NULL];
// Parse back using MSetRawMessageSet and check the contents.
MSetRawMessageSet* raw = [MSetRawMessageSet parseFromData:data error:NULL];
XCTAssertEqual([raw.unknownFields countOfFields], (NSUInteger)0);
XCTAssertEqual(raw.itemArray.count, (NSUInteger)3);
XCTAssertEqual((uint32_t)[raw.itemArray[0] typeId],
[TestMessageSetExtension1 messageSetExtension].fieldNumber);
[MSetMessageExtension1 messageSetExtension].fieldNumber);
XCTAssertEqual((uint32_t)[raw.itemArray[1] typeId],
[TestMessageSetExtension2 messageSetExtension].fieldNumber);
[MSetMessageExtension2 messageSetExtension].fieldNumber);
XCTAssertEqual([raw.itemArray[2] typeId], kUnknownTypeId);
TestMessageSetExtension1* message1 =
[TestMessageSetExtension1 parseFromData:[((RawMessageSet_Item*)raw.itemArray[0]) message]
error:NULL];
MSetMessageExtension1* message1 =
[MSetMessageExtension1 parseFromData:[((MSetRawMessageSet_Item*)raw.itemArray[0]) message]
error:NULL];
XCTAssertEqual(message1.i, 123);
TestMessageSetExtension2* message2 =
[TestMessageSetExtension2 parseFromData:[((RawMessageSet_Item*)raw.itemArray[1]) message]
error:NULL];
MSetMessageExtension2* message2 =
[MSetMessageExtension2 parseFromData:[((MSetRawMessageSet_Item*)raw.itemArray[1]) message]
error:NULL];
XCTAssertEqualObjects(message2.str, @"foo");
XCTAssertEqualObjects([raw.itemArray[2] message],
@ -187,29 +186,29 @@ const int kUnknownTypeId = 1550055;
}
- (void)testParseMessageSet {
// Set up a RawMessageSet with two known messages and an unknown one.
RawMessageSet* raw = [RawMessageSet message];
// Set up a MSetRawMessageSet with two known messages and an unknown one.
MSetRawMessageSet* raw = [MSetRawMessageSet message];
{
RawMessageSet_Item* item = [RawMessageSet_Item message];
item.typeId = [TestMessageSetExtension1 messageSetExtension].fieldNumber;
TestMessageSetExtension1* message = [TestMessageSetExtension1 message];
MSetRawMessageSet_Item* item = [MSetRawMessageSet_Item message];
item.typeId = [MSetMessageExtension1 messageSetExtension].fieldNumber;
MSetMessageExtension1* message = [MSetMessageExtension1 message];
message.i = 123;
item.message = [message data];
[raw.itemArray addObject:item];
}
{
RawMessageSet_Item* item = [RawMessageSet_Item message];
item.typeId = [TestMessageSetExtension2 messageSetExtension].fieldNumber;
TestMessageSetExtension2* message = [TestMessageSetExtension2 message];
MSetRawMessageSet_Item* item = [MSetRawMessageSet_Item message];
item.typeId = [MSetMessageExtension2 messageSetExtension].fieldNumber;
MSetMessageExtension2* message = [MSetMessageExtension2 message];
message.str = @"foo";
item.message = [message data];
[raw.itemArray addObject:item];
}
{
RawMessageSet_Item* item = [RawMessageSet_Item message];
MSetRawMessageSet_Item* item = [MSetRawMessageSet_Item message];
item.typeId = kUnknownTypeId;
item.message = [NSData dataWithBytes:"bar" length:3];
[raw.itemArray addObject:item];
@ -217,19 +216,19 @@ const int kUnknownTypeId = 1550055;
NSData* data = [raw data];
// Parse as a TestMessageSet and check the contents.
TestMessageSet* messageSet =
[TestMessageSet parseFromData:data
extensionRegistry:[UnittestMsetRoot extensionRegistry]
// Parse as a MSetMessage and check the contents.
MSetMessage* messageSet =
[MSetMessage parseFromData:data
extensionRegistry:[MSetUnittestMsetRoot extensionRegistry]
error:NULL];
XCTAssertEqual(
[[messageSet
getExtension:[TestMessageSetExtension1 messageSetExtension]] i],
getExtension:[MSetMessageExtension1 messageSetExtension]] i],
123);
XCTAssertEqualObjects(
[[messageSet
getExtension:[TestMessageSetExtension2 messageSetExtension]] str],
getExtension:[MSetMessageExtension2 messageSetExtension]] str],
@"foo");
XCTAssertEqual([messageSet.unknownFields countOfFields], (NSUInteger)1);

@ -30,11 +30,13 @@
syntax = "proto3";
package objc.protobuf.tests;
package objc.protobuf.tests.any;
import "google/protobuf/any.proto";
message TestAny {
option objc_class_prefix = "Any";
message TestMessage {
int32 int32_value = 1;
google.protobuf.Any any_value = 2;
repeated google.protobuf.Any repeated_any_value = 3;

@ -0,0 +1,12 @@
objc.protobuf.tests = "" # Explicit empty prefix
objc.protobuf.tests.any = Any
objc.protobuf.tests.chain = Chain
objc.protobuf.tests.cycle = Cycle
objc.protobuf.tests.deprecated = Dep
objc.protobuf.tests.deprecated_file = FileDep
objc.protobuf.tests.import = Import
objc.protobuf.tests.mset = MSet
objc.protobuf.tests.options = GPBTEST
objc.protobuf.tests.proto3_preserve_unknown_enum = UnknownEnums
objc.protobuf.tests.public_import = PublicImport
objc.protobuf.tests.startup = TestObjCStartup

@ -32,11 +32,11 @@ syntax = "proto2";
import "objectivec/Tests/unittest_import.proto";
// We don't put this in a package within proto2 because we need to make sure
// that the generated code doesn't depend on being in the proto2 namespace.
// In map_test_util.h we do "using namespace unittest = objc.protobuf.tests".
package objc.protobuf.tests;
// Explicit empty prefix, tests some validations code paths also.
option objc_class_prefix = "";
enum Proto2MapEnum {
PROTO2_MAP_ENUM_FOO = 0;
PROTO2_MAP_ENUM_BAR = 1;
@ -61,7 +61,7 @@ message TestEnumMapPlusExtra {
}
message TestImportEnumMap {
map<int32, objc.protobuf.tests.import.ImportEnumForMap> import_enum_amp = 1;
map<int32, objc.protobuf.tests.import.EnumForMap> import_enum_amp = 1;
}
message TestIntIntMap {

@ -32,11 +32,11 @@ syntax = "proto3";
import "objectivec/Tests/unittest.proto";
// We don't put this in a package within proto2 because we need to make sure
// that the generated code doesn't depend on being in the proto2 namespace.
// In map_test_util.h we do "using namespace unittest = objc.protobuf.tests".
package objc.protobuf.tests;
// Explicit empty prefix, tests some validations code paths also.
option objc_class_prefix = "";
// Tests maps.
message TestMap {
map<int32, int32> map_int32_int32 = 1;

@ -28,21 +28,15 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Author: kenton@google.com (Kenton Varda)
// Based on original Protocol Buffers design by
// Sanjay Ghemawat, Jeff Dean, and others.
//
// A proto file we will use for unit testing.
//
// LINT: ALLOW_GROUPS, LEGACY_NAMES
syntax = "proto2";
import "objectivec/Tests/unittest_import.proto";
// We don't put this in a package within proto2 because we need to make sure
// that the generated code doesn't depend on being in the proto2 namespace.
// In test_util.h we do "using namespace unittest = objc.protobuf.tests".
// Explicit empty prefix, tests some validations code paths also.
option objc_class_prefix = "";
package objc.protobuf.tests;
// This proto includes every type of field in both singular and repeated
@ -85,17 +79,17 @@ message TestAllTypes {
optional NestedMessage optional_nested_message = 18;
optional ForeignMessage optional_foreign_message = 19;
optional objc.protobuf.tests.import.ImportMessage optional_import_message = 20;
optional objc.protobuf.tests.import.Message optional_import_message = 20;
optional NestedEnum optional_nested_enum = 21;
optional ForeignEnum optional_foreign_enum = 22;
optional objc.protobuf.tests.import.ImportEnum optional_import_enum = 23;
optional objc.protobuf.tests.import.Enum optional_import_enum = 23;
optional string optional_string_piece = 24 [ctype=STRING_PIECE];
optional string optional_cord = 25 [ctype=CORD];
// Defined in unittest_import_public.proto
optional objc.protobuf.tests.import.PublicImportMessage
optional objc.protobuf.tests.public_import.Message
optional_public_import_message = 26;
optional NestedMessage optional_lazy_message = 27 [lazy=true];
@ -124,11 +118,11 @@ message TestAllTypes {
repeated NestedMessage repeated_nested_message = 48;
repeated ForeignMessage repeated_foreign_message = 49;
repeated objc.protobuf.tests.import.ImportMessage repeated_import_message = 50;
repeated objc.protobuf.tests.import.Message repeated_import_message = 50;
repeated NestedEnum repeated_nested_enum = 51;
repeated ForeignEnum repeated_foreign_enum = 52;
repeated objc.protobuf.tests.import.ImportEnum repeated_import_enum = 53;
repeated objc.protobuf.tests.import.Enum repeated_import_enum = 53;
repeated string repeated_string_piece = 54 [ctype=STRING_PIECE];
repeated string repeated_cord = 55 [ctype=CORD];
@ -154,7 +148,7 @@ message TestAllTypes {
optional NestedEnum default_nested_enum = 81 [default = BAR ];
optional ForeignEnum default_foreign_enum = 82 [default = FOREIGN_BAR];
optional objc.protobuf.tests.import.ImportEnum
optional objc.protobuf.tests.import.Enum
default_import_enum = 83 [default = IMPORT_BAR];
optional string default_string_piece = 84 [ctype=STRING_PIECE,default="abc"];
@ -241,18 +235,18 @@ extend TestAllExtensions {
optional TestAllTypes.NestedMessage optional_nested_message_extension = 18;
optional ForeignMessage optional_foreign_message_extension = 19;
optional objc.protobuf.tests.import.ImportMessage
optional objc.protobuf.tests.import.Message
optional_import_message_extension = 20;
optional TestAllTypes.NestedEnum optional_nested_enum_extension = 21;
optional ForeignEnum optional_foreign_enum_extension = 22;
optional objc.protobuf.tests.import.ImportEnum
optional objc.protobuf.tests.import.Enum
optional_import_enum_extension = 23;
optional string optional_string_piece_extension = 24 [ctype=STRING_PIECE];
optional string optional_cord_extension = 25 [ctype=CORD];
optional objc.protobuf.tests.import.PublicImportMessage
optional objc.protobuf.tests.public_import.Message
optional_public_import_message_extension = 26;
optional TestAllTypes.NestedMessage
@ -283,12 +277,12 @@ extend TestAllExtensions {
repeated TestAllTypes.NestedMessage repeated_nested_message_extension = 48;
repeated ForeignMessage repeated_foreign_message_extension = 49;
repeated objc.protobuf.tests.import.ImportMessage
repeated objc.protobuf.tests.import.Message
repeated_import_message_extension = 50;
repeated TestAllTypes.NestedEnum repeated_nested_enum_extension = 51;
repeated ForeignEnum repeated_foreign_enum_extension = 52;
repeated objc.protobuf.tests.import.ImportEnum
repeated objc.protobuf.tests.import.Enum
repeated_import_enum_extension = 53;
repeated string repeated_string_piece_extension = 54 [ctype=STRING_PIECE];
@ -318,7 +312,7 @@ extend TestAllExtensions {
default_nested_enum_extension = 81 [default = BAR];
optional ForeignEnum
default_foreign_enum_extension = 82 [default = FOREIGN_BAR];
optional objc.protobuf.tests.import.ImportEnum
optional objc.protobuf.tests.import.Enum
default_import_enum_extension = 83 [default = IMPORT_BAR];
optional string default_string_piece_extension = 84 [ctype=STRING_PIECE,

@ -29,7 +29,9 @@
syntax = "proto2";
package objc.protobuf.tests;
package objc.protobuf.tests.cycle;
option objc_class_prefix = "Cycle";
// Cycles in the Message graph can cause problems for message class
// initialization order.
@ -37,20 +39,20 @@ package objc.protobuf.tests;
// You can't make a object graph that spans files, so this can only be done
// within a single proto file.
message CycleFoo {
optional CycleFoo a_foo = 1;
optional CycleBar a_bar = 2;
optional CycleBaz a_baz = 3;
message Foo {
optional Foo a_foo = 1;
optional Bar a_bar = 2;
optional Baz a_baz = 3;
}
message CycleBar {
optional CycleBar a_bar = 1;
optional CycleBaz a_baz = 2;
optional CycleFoo a_foo = 3;
message Bar {
optional Bar a_bar = 1;
optional Baz a_baz = 2;
optional Foo a_foo = 3;
}
message CycleBaz {
optional CycleBaz a_baz = 1;
optional CycleFoo a_foo = 2;
optional CycleBar a_bar = 3;
message Baz {
optional Baz a_baz = 1;
optional Foo a_foo = 2;
optional Bar a_bar = 3;
}

@ -29,7 +29,7 @@
syntax = "proto2";
package objc.protobuf.tests;
package objc.protobuf.tests.chain;
import "objectivec/Tests/unittest.proto";
@ -37,15 +37,17 @@ import "objectivec/Tests/unittest_extension_chain_b.proto";
import "objectivec/Tests/unittest_extension_chain_c.proto";
import "objectivec/Tests/unittest_extension_chain_d.proto";
option objc_class_prefix = "Chain";
// The Root for this file should end up adding the local extension and merging
// in the extensions from D's Root (unittest and C will come via D's).
message ChainAMessage {
optional ChainBMessage b = 1;
optional ChainCMessage c = 2;
optional ChainDMessage d = 3;
message AMessage {
optional BMessage b = 1;
optional CMessage c = 2;
optional DMessage d = 3;
}
extend TestAllExtensions {
extend objc.protobuf.tests.TestAllExtensions {
optional int32 chain_a_extension = 10001;
}

@ -29,19 +29,21 @@
syntax = "proto2";
package objc.protobuf.tests;
package objc.protobuf.tests.chain;
import "objectivec/Tests/unittest.proto";
import "objectivec/Tests/unittest_extension_chain_c.proto";
option objc_class_prefix = "Chain";
// The Root for this file should end up adding the local extension and merging
// in the extensions from C's Root (unittest will come via C's).
message ChainBMessage {
optional ChainCMessage c = 1;
message BMessage {
optional CMessage c = 1;
}
extend TestAllExtensions {
extend objc.protobuf.tests.TestAllExtensions {
optional int32 chain_b_extension = 10002;
}

@ -29,17 +29,19 @@
syntax = "proto2";
package objc.protobuf.tests;
package objc.protobuf.tests.chain;
import "objectivec/Tests/unittest.proto";
option objc_class_prefix = "Chain";
// The Root for this file should end up adding the local extension and merging
// in the extensions from unittest.proto's Root.
message ChainCMessage {
message CMessage {
optional int32 my_field = 1;
}
extend TestAllExtensions {
extend objc.protobuf.tests.TestAllExtensions {
optional int32 chain_c_extension = 10003;
}

@ -29,21 +29,23 @@
syntax = "proto2";
package objc.protobuf.tests;
package objc.protobuf.tests.chain;
import "objectivec/Tests/unittest.proto";
import "objectivec/Tests/unittest_extension_chain_b.proto";
import "objectivec/Tests/unittest_extension_chain_c.proto";
option objc_class_prefix = "Chain";
// The root should end up needing to merge B (C will be merged into B, so it
// doesn't need to be directly merged).
message ChainDMessage {
optional ChainBMessage b = 1;
optional ChainCMessage c = 2;
message DMessage {
optional BMessage b = 1;
optional CMessage c = 2;
}
extend TestAllExtensions {
extend objc.protobuf.tests.TestAllExtensions {
optional int32 chain_d_extension = 10004;
}

@ -29,12 +29,14 @@
syntax = "proto2";
package objc.protobuf.tests;
package objc.protobuf.tests.chain;
import "objectivec/Tests/unittest.proto";
option objc_class_prefix = "Chain";
// The Root for this file should end up just merging in unittest's Root.
message ChainEMessage {
message EMessage {
optional TestAllTypes my_field = 1;
}

@ -29,16 +29,18 @@
syntax = "proto2";
package objc.protobuf.tests;
package objc.protobuf.tests.chain;
import "objectivec/Tests/unittest_extension_chain_g.proto";
option objc_class_prefix = "Chain";
// The Root for this file should just be merging in the extensions from C's
// Root (because G doesn't define anything itself).
// The generated source will also have to directly import C's .h file so it can
// compile the reference to C's Root class.
message ChainFMessage {
optional ChainGMessage g = 1;
message FMessage {
optional GMessage g = 1;
}

@ -29,13 +29,15 @@
syntax = "proto2";
package objc.protobuf.tests;
package objc.protobuf.tests.chain;
import "objectivec/Tests/unittest_extension_chain_c.proto";
option objc_class_prefix = "Chain";
// The Root for this file should just be merging in the extensions from C's
// Root.
message ChainGMessage {
optional ChainCMessage c = 1;
message GMessage {
optional CMessage c = 1;
}

@ -28,10 +28,6 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Author: kenton@google.com (Kenton Varda)
// Based on original Protocol Buffers design by
// Sanjay Ghemawat, Jeff Dean, and others.
//
// A proto file which is imported by unittest.proto to test importing.
syntax = "proto2";
@ -41,11 +37,13 @@ package objc.protobuf.tests.import;
// Test public import
import public "objectivec/Tests/unittest_import_public.proto";
message ImportMessage {
option objc_class_prefix = "Import";
message Message {
optional int32 d = 1;
}
enum ImportEnum {
enum Enum {
IMPORT_FOO = 7;
IMPORT_BAR = 8;
IMPORT_BAZ = 9;
@ -53,7 +51,7 @@ enum ImportEnum {
// To use an enum in a map, it must has the first value as 0.
enum ImportEnumForMap {
enum EnumForMap {
UNKNOWN = 0;
FOO = 1;
BAR = 2;

@ -32,8 +32,10 @@
syntax = "proto2";
package objc.protobuf.tests.import;
package objc.protobuf.tests.public_import;
message PublicImportMessage {
option objc_class_prefix = "PublicImport";
message Message {
optional int32 e = 1;
}

@ -28,68 +28,34 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Author: kenton@google.com (Kenton Varda)
// Based on original Protocol Buffers design by
// Sanjay Ghemawat, Jeff Dean, and others.
//
// This file is similar to unittest_mset_wire_format.proto, but does not
// have a TestMessageSet, so it can be downgraded to proto1.
syntax = "proto2";
import "objectivec/Tests/unittest_mset_wire_format.proto";
package objc.protobuf.tests;
message TestMessageSetContainer {
optional objc.protobuf.tests.wireformat.TestMessageSet message_set = 1;
}
package objc.protobuf.tests.mset;
message NestedTestMessageSetContainer {
optional TestMessageSetContainer container = 1;
optional NestedTestMessageSetContainer child = 2;
}
option objc_class_prefix = "MSet";
message NestedTestInt {
optional fixed32 a = 1;
optional int32 b = 3;
optional NestedTestInt child = 2;
// A message with message_set_wire_format.
message Message {
option message_set_wire_format = true;
extensions 4 to max;
}
message TestMessageSetExtension1 {
extend objc.protobuf.tests.wireformat.TestMessageSet {
optional TestMessageSetExtension1 message_set_extension = 1545008;
message MessageExtension1 {
extend Message {
optional MessageExtension1 message_set_extension = 1545008;
}
optional int32 i = 15;
optional objc.protobuf.tests.wireformat.TestMessageSet recursive = 16;
optional Message recursive = 16;
optional string test_aliasing = 17 [ctype = STRING_PIECE];
}
message TestMessageSetExtension2 {
extend objc.protobuf.tests.wireformat.TestMessageSet {
optional TestMessageSetExtension2 message_set_extension = 1547769;
message MessageExtension2 {
extend Message {
optional MessageExtension2 message_set_extension = 1547769;
}
optional string str = 25;
}
message TestMessageSetExtension3 {
extend objc.protobuf.tests.wireformat.TestMessageSet {
optional TestMessageSetExtension3 message_set_extension = 195273129;
}
optional NestedTestInt msg = 35;
}
// This message was used to generate
// //net/proto2/python/internal/testdata/message_set_message, but is commented
// out since it must not actually exist in code, to simulate an "unknown"
// extension.
// message TestMessageSetUnknownExtension {
// extend TestMessageSet {
// optional TestMessageSetUnknownExtension message_set_extension = 56141421;
// }
// optional int64 a = 1;
// }
// MessageSet wire format is equivalent to this.
message RawMessageSet {
repeated group Item = 1 {

@ -34,6 +34,9 @@ import "objectivec/Tests/unittest.proto";
package objc.protobuf.tests;
// Explicit empty prefix, tests some validations code paths also.
option objc_class_prefix = "";
// Used to check that Headerdocs and appledoc work correctly. If these comments
// are not handled correctly, Xcode will fail to build the tests.
message TestGeneratedComments {

@ -31,19 +31,20 @@
syntax = "proto2";
package objc.protobuf.tests.startup;
option objc_class_prefix = "TestObjCStartup";
message TestObjCStartupMessage {
message Message {
extensions 1 to max;
}
extend TestObjCStartupMessage {
extend Message {
// Singular
optional int32 optional_int32_extension = 1;
repeated int32 repeated_int32_extension = 2;
}
message TestObjCStartupNested {
extend TestObjCStartupMessage {
message Nested {
extend Message {
optional string nested_string_extension = 3;
}
}

@ -29,8 +29,11 @@
syntax = "proto2";
// Explicit empty prefix, tests some validations code paths also.
package objc.protobuf.tests;
option objc_class_prefix = "";
message Message2 {
enum Enum {
FOO = 0;

@ -29,8 +29,11 @@
syntax = "proto3";
// Explicit empty prefix, tests some validations code paths also.
package objc.protobuf.tests;
option objc_class_prefix = "";
message Message3 {
enum Enum {
FOO = 0;

@ -9,7 +9,6 @@ load("//conformance:defs.bzl", "conformance_test")
filegroup(
name = "source_files",
visibility = [
"//benchmarks/php:__pkg__",
"//conformance:__pkg__",
"//php:__pkg__",
],

@ -65,6 +65,8 @@ sudo pecl install protobuf-{VERSION}
Simply add "google/protobuf" to the 'require' section of composer.json in your
project.
To use the pure PHP implementation, you need to install bcmath.
### Protoc
Once the extension or package is installed, if you wish to generate PHP code

@ -30,5 +30,8 @@
"test_valgrind": "./generate_test_protos.sh && ./tests/compile_extension.sh && ZEND_DONT_UNLOAD_MODULES=1 USE_ZEND_ALLOC=0 valgrind --leak-check=full --error-exitcode=1 php -dextension=ext/google/protobuf/modules/protobuf.so vendor/bin/phpunit --bootstrap tests/force_c_ext.php tests",
"test": "./generate_test_protos.sh && vendor/bin/phpunit tests",
"aggregate_metadata_test": "./generate_test_protos.sh --aggregate_metadata && vendor/bin/phpunit tests"
},
"config": {
"process-timeout": 1200
}
}

@ -1,6 +1,6 @@
#!/bin/bash
set -e
set -ex
cd $(dirname $0)/..

@ -88,7 +88,6 @@ pkg_filegroup(
srcs = [
":dist_files",
"//:common_dist_files",
"//benchmarks:all_dist_files",
"//build_defs:dist_files",
"//conformance:all_dist_files",
"//src:all_dist_files",

@ -555,6 +555,21 @@ def internal_py_proto_library(
**kargs
)
def py_proto_library(
*args,
**kwargs):
"""Deprecated alias for use before Bazel 5.3.
Args:
*args: the name of the py_proto_library.
**kwargs: other keyword arguments that are passed to py_library.
Deprecated:
This is provided for backwards compatibility only. Bazel 5.3 will
introduce support for py_proto_library, which should be used instead.
"""
internal_py_proto_library(*args, **kwargs)
def _source_proto_library(
name,
srcs = [],

@ -151,12 +151,6 @@ def Type():
return _implementation_type
def _SetType(implementation_type):
"""Never use! Only for protobuf benchmark."""
global _implementation_type
_implementation_type = implementation_type
# See comment on 'Type' above.
# TODO(jieluo): Remove the API, it returns a constant. b/228102101
def Version():

@ -889,6 +889,7 @@ class MessageTest(unittest.TestCase):
def testOneofClearField(self, message_module):
m = message_module.TestAllTypes()
m.ClearField('oneof_field')
m.oneof_uint32 = 11
m.ClearField('oneof_field')
if message_module is unittest_pb2:

@ -30,7 +30,7 @@
// Author: qrczak@google.com (Marcin Kowalczyk)
#include <google/protobuf/python/python_protobuf.h>
#include "google/protobuf/python/python_protobuf.h"
namespace google {
namespace protobuf {

@ -2485,6 +2485,5 @@ class OptionalColonMessageToStringTest(unittest.TestCase):
if __name__ == '__main__':
unittest.main()

@ -48,8 +48,8 @@
#define PY_SSIZE_T_CLEAN
#include <Python.h>
#include <google/protobuf/descriptor_database.h>
#include <google/protobuf/message.h>
#include "google/protobuf/descriptor_database.h"
#include "google/protobuf/message.h"
namespace google {
namespace protobuf {

@ -30,7 +30,7 @@
// Author: petar@google.com (Petar Petrov)
#include <google/protobuf/pyext/descriptor.h>
#include "google/protobuf/pyext/descriptor.h"
#define PY_SSIZE_T_CLEAN
#include <Python.h>
@ -40,15 +40,15 @@
#include <string>
#include <unordered_map>
#include <google/protobuf/descriptor.pb.h>
#include <google/protobuf/dynamic_message.h>
#include <google/protobuf/pyext/descriptor_containers.h>
#include <google/protobuf/pyext/descriptor_pool.h>
#include <google/protobuf/pyext/message.h>
#include <google/protobuf/pyext/message_factory.h>
#include <google/protobuf/pyext/scoped_pyobject_ptr.h>
#include "google/protobuf/descriptor.pb.h"
#include "google/protobuf/dynamic_message.h"
#include "google/protobuf/pyext/descriptor_containers.h"
#include "google/protobuf/pyext/descriptor_pool.h"
#include "google/protobuf/pyext/message.h"
#include "google/protobuf/pyext/message_factory.h"
#include "google/protobuf/pyext/scoped_pyobject_ptr.h"
#include "absl/strings/string_view.h"
#include <google/protobuf/io/coded_stream.h>
#include "google/protobuf/io/coded_stream.h"
#define PyString_AsStringAndSize(ob, charpp, sizep) \
(PyUnicode_Check(ob) \

@ -36,7 +36,7 @@
#define PY_SSIZE_T_CLEAN
#include <Python.h>
#include <google/protobuf/descriptor.h>
#include "google/protobuf/descriptor.h"
namespace google {
namespace protobuf {

@ -54,13 +54,13 @@
// This inclusion must appear before all the others.
#include <Python.h>
#include <google/protobuf/pyext/descriptor_containers.h>
#include "google/protobuf/pyext/descriptor_containers.h"
// clang-format on
#include <google/protobuf/descriptor.h>
#include <google/protobuf/pyext/descriptor.h>
#include <google/protobuf/pyext/descriptor_pool.h>
#include <google/protobuf/pyext/scoped_pyobject_ptr.h>
#include "google/protobuf/descriptor.h"
#include "google/protobuf/pyext/descriptor.h"
#include "google/protobuf/pyext/descriptor_pool.h"
#include "google/protobuf/pyext/scoped_pyobject_ptr.h"
#include "absl/strings/string_view.h"
#define PyString_AsStringAndSize(ob, charpp, sizep) \

@ -31,15 +31,15 @@
// This file defines a C++ DescriptorDatabase, which wraps a Python Database
// and delegate all its operations to Python methods.
#include <google/protobuf/pyext/descriptor_database.h>
#include "google/protobuf/pyext/descriptor_database.h"
#include <cstdint>
#include <google/protobuf/stubs/logging.h>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/descriptor.pb.h>
#include <google/protobuf/pyext/message.h>
#include <google/protobuf/pyext/scoped_pyobject_ptr.h>
#include "google/protobuf/stubs/logging.h"
#include "google/protobuf/stubs/common.h"
#include "google/protobuf/descriptor.pb.h"
#include "google/protobuf/pyext/message.h"
#include "google/protobuf/pyext/scoped_pyobject_ptr.h"
namespace google {
namespace protobuf {

@ -34,7 +34,7 @@
#define PY_SSIZE_T_CLEAN
#include <Python.h>
#include <google/protobuf/descriptor_database.h>
#include "google/protobuf/descriptor_database.h"
namespace google {
namespace protobuf {

@ -35,13 +35,13 @@
#define PY_SSIZE_T_CLEAN
#include <Python.h>
#include <google/protobuf/descriptor.pb.h>
#include <google/protobuf/pyext/descriptor.h>
#include <google/protobuf/pyext/descriptor_database.h>
#include <google/protobuf/pyext/descriptor_pool.h>
#include <google/protobuf/pyext/message.h>
#include <google/protobuf/pyext/message_factory.h>
#include <google/protobuf/pyext/scoped_pyobject_ptr.h>
#include "google/protobuf/descriptor.pb.h"
#include "google/protobuf/pyext/descriptor.h"
#include "google/protobuf/pyext/descriptor_database.h"
#include "google/protobuf/pyext/descriptor_pool.h"
#include "google/protobuf/pyext/message.h"
#include "google/protobuf/pyext/message_factory.h"
#include "google/protobuf/pyext/scoped_pyobject_ptr.h"
#include "absl/strings/string_view.h"
#define PyString_AsStringAndSize(ob, charpp, sizep) \

@ -35,7 +35,7 @@
#include <Python.h>
#include <unordered_map>
#include <google/protobuf/descriptor.h>
#include "google/protobuf/descriptor.h"
namespace google {
namespace protobuf {

@ -31,23 +31,23 @@
// Author: anuraag@google.com (Anuraag Agrawal)
// Author: tibell@google.com (Johan Tibell)
#include <google/protobuf/pyext/extension_dict.h>
#include "google/protobuf/pyext/extension_dict.h"
#include <cstdint>
#include <memory>
#include <google/protobuf/stubs/logging.h>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/descriptor.pb.h>
#include <google/protobuf/descriptor.h>
#include <google/protobuf/dynamic_message.h>
#include <google/protobuf/message.h>
#include <google/protobuf/pyext/descriptor.h>
#include <google/protobuf/pyext/message.h>
#include <google/protobuf/pyext/message_factory.h>
#include <google/protobuf/pyext/repeated_composite_container.h>
#include <google/protobuf/pyext/repeated_scalar_container.h>
#include <google/protobuf/pyext/scoped_pyobject_ptr.h>
#include "google/protobuf/stubs/logging.h"
#include "google/protobuf/stubs/common.h"
#include "google/protobuf/descriptor.pb.h"
#include "google/protobuf/descriptor.h"
#include "google/protobuf/dynamic_message.h"
#include "google/protobuf/message.h"
#include "google/protobuf/pyext/descriptor.h"
#include "google/protobuf/pyext/message.h"
#include "google/protobuf/pyext/message_factory.h"
#include "google/protobuf/pyext/repeated_composite_container.h"
#include "google/protobuf/pyext/repeated_scalar_container.h"
#include "google/protobuf/pyext/scoped_pyobject_ptr.h"
#include "absl/strings/string_view.h"
#define PyString_AsStringAndSize(ob, charpp, sizep) \

@ -37,7 +37,7 @@
#define PY_SSIZE_T_CLEAN
#include <Python.h>
#include <google/protobuf/pyext/message.h>
#include "google/protobuf/pyext/message.h"
namespace google {
namespace protobuf {

@ -28,11 +28,11 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <google/protobuf/pyext/field.h>
#include "google/protobuf/pyext/field.h"
#include <google/protobuf/descriptor.h>
#include <google/protobuf/pyext/descriptor.h>
#include <google/protobuf/pyext/message.h>
#include "google/protobuf/descriptor.h"
#include "google/protobuf/pyext/descriptor.h"
#include "google/protobuf/pyext/message.h"
namespace google {
namespace protobuf {

@ -30,21 +30,21 @@
// Author: haberman@google.com (Josh Haberman)
#include <google/protobuf/pyext/map_container.h>
#include "google/protobuf/pyext/map_container.h"
#include <cstdint>
#include <memory>
#include <google/protobuf/stubs/logging.h>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/map.h>
#include <google/protobuf/map_field.h>
#include <google/protobuf/message.h>
#include <google/protobuf/pyext/message.h>
#include <google/protobuf/pyext/message_factory.h>
#include <google/protobuf/pyext/repeated_composite_container.h>
#include <google/protobuf/pyext/scoped_pyobject_ptr.h>
#include <google/protobuf/stubs/map_util.h>
#include "google/protobuf/stubs/logging.h"
#include "google/protobuf/stubs/common.h"
#include "google/protobuf/map.h"
#include "google/protobuf/map_field.h"
#include "google/protobuf/message.h"
#include "google/protobuf/pyext/message.h"
#include "google/protobuf/pyext/message_factory.h"
#include "google/protobuf/pyext/repeated_composite_container.h"
#include "google/protobuf/pyext/scoped_pyobject_ptr.h"
#include "util/gtl/map_util.h"
namespace google {
namespace protobuf {

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save