Merge branch 'master' into 3.15.x

pull/8447/head
Adam Cozzette 4 years ago
commit 87aa9adb86
  1. 4
      .github/mergeable.yml
  2. 2
      .github/workflows/codespell.yml
  3. 1
      .gitignore
  4. 44
      BUILD
  5. 42
      CHANGES.txt
  6. 1
      Makefile.am
  7. 21
      WORKSPACE
  8. 65
      benchmarks/BUILD
  9. 15
      benchmarks/cpp/BUILD
  10. 59
      benchmarks/datasets/BUILD
  11. 44
      benchmarks/datasets/google_message1/proto2/BUILD
  12. 44
      benchmarks/datasets/google_message1/proto3/BUILD
  13. 44
      benchmarks/datasets/google_message2/BUILD
  14. 50
      benchmarks/datasets/google_message3/BUILD
  15. 45
      benchmarks/datasets/google_message4/BUILD
  16. 4
      cmake/install.cmake
  17. 6
      cmake/protobuf-config.cmake.in
  18. 13
      configure.ac
  19. 2
      conformance/binary_json_conformance_suite.cc
  20. 7
      conformance/conformance_cpp.cc
  21. 4
      conformance/conformance_test_runner.cc
  22. 21
      conformance/text_format_conformance_suite.cc
  23. 2
      csharp/install_dotnet_sdk.ps1
  24. 2
      csharp/src/Google.Protobuf.Benchmarks/Google.Protobuf.Benchmarks.csproj
  25. 232
      csharp/src/Google.Protobuf.Test.TestProtos/UnittestProto3Optional.cs
  26. 12
      csharp/src/Google.Protobuf.Test/Buffers/ArrayBufferWriter.cs
  27. 61
      csharp/src/Google.Protobuf.Test/CodedOutputStreamTest.cs
  28. 2
      csharp/src/Google.Protobuf.Test/Google.Protobuf.Test.csproj
  29. 4
      csharp/src/Google.Protobuf.Test/JsonParserTest.cs
  30. 4
      csharp/src/Google.Protobuf.Test/JsonTokenizerTest.cs
  31. 2
      csharp/src/Google.Protobuf.Test/LegacyGeneratedCodeTest.cs
  32. 6
      csharp/src/Google.Protobuf.Test/MessageParsingHelpers.cs
  33. BIN
      csharp/src/Google.Protobuf.Test/testprotos.pb
  34. 16
      csharp/src/Google.Protobuf/Google.Protobuf.csproj
  35. 111
      csharp/src/Google.Protobuf/Reflection/Descriptor.cs
  36. 117
      csharp/src/Google.Protobuf/WritingPrimitives.cs
  37. 4
      docs/implementing_proto3_presence.md
  38. 18
      docs/jvm_aot.md
  39. 12
      docs/options.md
  40. 2
      docs/third_party.md
  41. 2
      global.json
  42. 4
      java/README.md
  43. 1
      java/core/BUILD
  44. 6
      java/core/src/main/java/com/google/protobuf/ByteString.java
  45. 72
      java/core/src/main/java/com/google/protobuf/CodedInputStream.java
  46. 2
      java/core/src/main/java/com/google/protobuf/FieldSet.java
  47. 21
      java/core/src/main/java/com/google/protobuf/GeneratedMessageLite.java
  48. 23
      java/core/src/main/java/com/google/protobuf/InvalidProtocolBufferException.java
  49. 7
      java/core/src/main/java/com/google/protobuf/RopeByteString.java
  50. 2
      java/core/src/main/java/com/google/protobuf/UnsafeUtil.java
  51. 4
      java/core/src/test/java/com/google/protobuf/AbstractMessageTest.java
  52. 78
      java/core/src/test/java/com/google/protobuf/CodedInputStreamTest.java
  53. 2
      java/core/src/test/java/com/google/protobuf/DynamicMessageTest.java
  54. 1
      java/core/src/test/java/com/google/protobuf/GeneratedMessageTest.java
  55. 4
      java/core/src/test/java/com/google/protobuf/MapForProto2Test.java
  56. 4
      java/core/src/test/java/com/google/protobuf/MapTest.java
  57. 6
      java/core/src/test/java/com/google/protobuf/TestBadIdentifiers.java
  58. 6
      java/core/src/test/java/com/google/protobuf/TestBadIdentifiersLite.java
  59. 56
      java/core/src/test/proto/com/google/protobuf/test_extra_interfaces.proto
  60. 1
      java/lite/generate-test-sources-build.xml
  61. 1
      java/lite/pom.xml
  62. 194
      java/lite/src/test/java/com/google/protobuf/LiteTest.java
  63. 8
      java/pom.xml
  64. 13
      java/util/src/main/java/com/google/protobuf/util/Durations.java
  65. 10
      kokoro/linux/dockerfile/test/csharp/Dockerfile
  66. 17
      kokoro/linux/python/build.sh
  67. 11
      kokoro/linux/python/continuous.cfg
  68. 11
      kokoro/linux/python/presubmit.cfg
  69. 2
      kokoro/release/protoc/linux/build.sh
  70. 22
      kokoro/release/python/linux/build_artifacts.sh
  71. 57
      kokoro/release/python/linux/config.sh
  72. 49
      objectivec/GPBExtensionRegistry.m
  73. 4
      php/README.md
  74. 64
      php/src/Google/Protobuf/Internal/FileOptions.php
  75. 10
      php/src/Google/Protobuf/Internal/RepeatedField.php
  76. 4
      protoc-artifacts/README.md
  77. 6
      protoc-artifacts/build-protoc.sh
  78. 4
      protoc-artifacts/build-zip.sh
  79. 4
      protoc-artifacts/pom.xml
  80. 9
      python/google/protobuf/internal/message_test.py
  81. 6
      python/google/protobuf/internal/python_message.py
  82. 55
      python/google/protobuf/internal/text_format_test.py
  83. 18
      python/google/protobuf/pyext/descriptor.cc
  84. 4
      python/google/protobuf/pyext/descriptor_database.cc
  85. 5
      python/google/protobuf/pyext/descriptor_pool.cc
  86. 6
      python/google/protobuf/pyext/extension_dict.cc
  87. 17
      python/google/protobuf/pyext/map_container.cc
  88. 3
      python/google/protobuf/pyext/map_container.h
  89. 38
      python/google/protobuf/pyext/message.cc
  90. 11
      python/google/protobuf/pyext/message.h
  91. 5
      python/google/protobuf/pyext/message_factory.cc
  92. 9
      python/google/protobuf/pyext/repeated_scalar_container.cc
  93. 4
      python/google/protobuf/text_format.py
  94. 20
      python/setup.py
  95. 7
      python/tox.ini
  96. 6
      ruby/ext/google/protobuf_c/protobuf.c
  97. 2
      src/Makefile.am
  98. 15
      src/google/protobuf/any.pb.cc
  99. 77
      src/google/protobuf/any.pb.h
  100. 33
      src/google/protobuf/api.pb.cc
  101. Some files were not shown because too many files have changed in this diff Show More

@ -11,8 +11,8 @@ mergeable:
regex: 'release notes: yes'
message: 'Please include release notes: yes'
- must_include:
regex: '^(c#|c\+\+|cleanup|conformance tests|integration|java|javascript|go|objective-c|php|python|ruby|bazel|cmake|protoc)'
message: 'Please include at least a language label (e.g., c++, java, python). Or apply one of the following labels: bazel, cmake, cleanup, conformance tests, integration, protoc.'
regex: '^(autotools|bazel|c#|c\+\+|cleanup|cmake|conformance tests|integration|go|java|javascript|objective-c|php|protoc|python|ruby|kotlin)'
message: 'Please include at least a language label (e.g., c++, java, python). Or apply one of the following labels: autotools, bazel, cmake, cleanup, conformance tests, integration, protoc.'
- must_include:
regex: 'release notes: no'
message: 'Please include release notes: no'

@ -13,4 +13,4 @@ jobs:
with:
check_filenames: true
skip: ./.git,./conformance/third_party,*.snk,*.pb,*.pb.cc,*.pb.h,./src/google/protobuf/testdata,./objectivec/Tests,./python/compatibility_tests/v2.5.0/tests/google/protobuf/internal
ignore_words_list: "alow,alse,ba,cleare,copyable,cloneable,dedup,dur,errorprone,files',fo,fundementals,hel,importd,inout,leapyear,nd,nin,ois,ons,parseable,process',te,testof,ue,unparseable,wasn,wee,gae,keyserver,objext,od"
ignore_words_list: "alow,alse,ba,cleare,copyable,cloneable,dedup,dur,errorprone,files',fo,fundementals,hel,importd,inout,leapyear,nd,nin,ois,ons,parseable,process',te,testof,ue,unparseable,wasn,wee,gae,keyserver,objext,od,OptIn"

1
.gitignore vendored

@ -83,6 +83,7 @@ src/**/*.trs
# JavaBuild output.
java/core/target
java/lite/target
java/util/target
javanano/target
java/.idea

44
BUILD

@ -14,38 +14,6 @@ exports_files(["LICENSE"])
# build configuration
################################################################################
# TODO(yannic): Remove in 3.14.0.
string_flag(
name = "incompatible_use_com_google_googletest",
build_setting_default = "true",
values = ["true", "false"]
)
config_setting(
name = "use_com_google_googletest",
flag_values = {
"//:incompatible_use_com_google_googletest": "true"
},
)
GTEST = select({
"//:use_com_google_googletest": [
"@com_google_googletest//:gtest",
],
"//conditions:default": [
"//external:gtest",
],
})
GTEST_MAIN = select({
"//:use_com_google_googletest": [
"@com_google_googletest//:gtest_main",
],
"//conditions:default": [
"//external:gtest_main",
],
})
################################################################################
# ZLIB configuration
################################################################################
@ -571,6 +539,7 @@ COMMON_TEST_SRCS = [
cc_binary(
name = "test_plugin",
testonly = True,
srcs = [
# AUTOGEN(test_plugin_srcs)
"src/google/protobuf/compiler/mock_code_generator.cc",
@ -580,7 +549,8 @@ cc_binary(
deps = [
":protobuf",
":protoc_lib",
] + GTEST,
"@com_google_googletest//:gtest",
],
)
cc_test(
@ -592,7 +562,9 @@ cc_test(
],
deps = [
":protobuf_lite",
] + GTEST_MAIN,
"@com_google_googletest//:gtest",
"@com_google_googletest//:gtest_main",
],
)
cc_test(
@ -695,7 +667,9 @@ cc_test(
":cc_test_protos",
":protobuf",
":protoc_lib",
] + PROTOBUF_DEPS + GTEST_MAIN,
"@com_google_googletest//:gtest",
"@com_google_googletest//:gtest_main",
] + PROTOBUF_DEPS,
)
################################################################################

@ -1,3 +1,45 @@
Unreleased Changes (C++/Java/Python/PHP/Objective-C/C#/Ruby/JavaScript)
C++
* The ::pb namespace is no longer exposed due to conflicts.
* Allow MessageDifferencer::TreatAsSet() (and friends) to override previous
calls instead of crashing.
* Reduce the size of generated proto headers for protos with `string` or
`bytes` fields.
* Move arena() operation on uncommon path to out-of-line routine
* For iterator-pair function parameter types, take both iterators by value.
* Code-space savings and perhaps some modest performance improvements in
RepeatedPtrField.
* Eliminate nullptr check from every tag parse.
* Remove unused _$name$_cached_byte_size_ fields.
* Serialize extension ranges together when not broken by a proto field in the
middle.
* Do out-of-line allocation and deallocation of string object in ArenaString.
* Streamline ParseContext::ParseMessage<T> to avoid code bloat and improve
performance.
* New member functions RepeatedField::Assign, RepeatedPtrField::{Add, Assign}.
* Fix undefined behavior warning due to innocuous uninitialization of value
on an error path.
* Avoid expensive inlined code space for encoding message length for messages
>= 128 bytes and instead do a procedure call to a shared out-of-line routine.
* util::DefaultFieldComparator will be final in a future version of protobuf.
Subclasses should inherit from SimpleFieldComparator instead.
Java:
* Detect invalid overflow of byteLimit and return InvalidProtocolBufferException as documented.
* Exceptions thrown while reading from an InputStream in parseFrom are now
included as causes.
* Support potentially more efficient proto parsing from RopeByteStrings.
* Clarify runtime of ByteString.Output.toStringBuffer().
Python
* Fixed a bug in text format where a trailing colon was printed for repeated field.
* When TextFormat encounters a duplicate message map key, replace the current
one instead of merging.
JavaScript
* Make Any.pack() chainable.
2021-04-02 version 3.15.7 (C++/Java/Python/PHP/Objective-C/C#/Ruby/JavaScript)
C++

@ -529,7 +529,6 @@ java_EXTRA_DIST=
java/core/src/test/proto/com/google/protobuf/test_check_utf8.proto \
java/core/src/test/proto/com/google/protobuf/test_check_utf8_size.proto \
java/core/src/test/proto/com/google/protobuf/test_custom_options.proto \
java/core/src/test/proto/com/google/protobuf/test_extra_interfaces.proto \
java/core/src/test/proto/com/google/protobuf/wrappers_test.proto \
java/lite.md \
java/lite/BUILD \

@ -17,6 +17,15 @@ http_archive(
],
)
http_archive(
name = "com_github_google_benchmark",
sha256 = "2a778d821997df7d8646c9c59b8edb9a573a6e04c534c01892a40aa524a7b68c",
strip_prefix = "benchmark-bf585a2789e30585b4e3ce6baf11ef2750b54677",
urls = [
"https://github.com/google/benchmark/archive/bf585a2789e30585b4e3ce6baf11ef2750b54677.zip",
],
)
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
load("//:protobuf_deps.bzl", "protobuf_deps")
@ -29,18 +38,6 @@ bind(
actual = "//util/python:python_headers",
)
# TODO(yannic): Remove in 3.14.0.
bind(
name = "gtest",
actual = "@com_google_googletest//:gtest",
)
# TODO(yannic): Remove in 3.14.0.
bind(
name = "gtest_main",
actual = "@com_google_googletest//:gtest_main",
)
jvm_maven_import_external(
name = "guava_maven",
artifact = "com.google.guava:guava:18.0",

@ -0,0 +1,65 @@
load("@rules_cc//cc:defs.bzl", "cc_proto_library")
load("@rules_java//java:defs.bzl", "java_proto_library")
load("@rules_proto//proto:defs.bzl", "proto_library")
proto_library(
name = "benchmarks_proto",
srcs = [
"benchmarks.proto",
],
strip_import_prefix = "/benchmarks",
visibility = [
"//benchmarks:__subpackages__",
],
)
cc_proto_library(
name = "benchmarks_cc_proto",
visibility = [
"//benchmarks:__subpackages__",
],
deps = [
"benchmarks_proto",
],
)
java_proto_library(
name = "benchmarks_java_proto",
visibility = [
"//benchmarks:__subpackages__",
],
deps = [
"benchmarks_proto",
],
)
proto_library(
name = "google_size_proto",
srcs = [
"google_size.proto",
],
strip_import_prefix = "/benchmarks",
visibility = [
"//benchmarks:__subpackages__",
],
)
cc_proto_library(
name = "google_size_cc_proto",
visibility = [
"//benchmarks:__subpackages__",
],
deps = [
"google_size_proto",
],
)
java_proto_library(
name = "google_size_java_proto",
visibility = [
"//benchmarks:__subpackages__",
],
deps = [
"google_size_proto",
],
)

@ -0,0 +1,15 @@
load("@rules_cc//cc:defs.bzl", "cc_binary")
cc_binary(
name = "cpp",
srcs = [
"cpp_benchmark.cc",
],
tags = ["benchmark"],
deps = [
"//:protobuf",
"//benchmarks:benchmarks_cc_proto",
"//benchmarks/datasets:cc_protos",
"@com_github_google_benchmark//:benchmark_main",
],
)

@ -0,0 +1,59 @@
load("@rules_cc//cc:defs.bzl", "cc_library")
load("@rules_java//java:defs.bzl", "java_library")
load("@rules_proto//proto:defs.bzl", "proto_library")
filegroup(
name = "datasets",
srcs = [
"//benchmarks/datasets/google_message1/proto2:datasets",
"//benchmarks/datasets/google_message1/proto3:datasets",
"//benchmarks/datasets/google_message2:datasets",
"//benchmarks/datasets/google_message3:datasets",
"//benchmarks/datasets/google_message4:datasets",
],
visibility = [
"//benchmarks:__subpackages__",
],
)
proto_library(
name = "protos",
visibility = [
"//benchmarks:__subpackages__",
],
deps = [
"//benchmarks/datasets/google_message1/proto2:benchmark_message1_proto2_proto",
"//benchmarks/datasets/google_message1/proto3:benchmark_message1_proto3_proto",
"//benchmarks/datasets/google_message2:benchmark_message2_proto",
"//benchmarks/datasets/google_message3:benchmark_message3_proto",
"//benchmarks/datasets/google_message4:benchmark_message4_proto",
],
)
cc_library(
name = "cc_protos",
visibility = [
"//benchmarks:__subpackages__",
],
deps = [
"//benchmarks/datasets/google_message1/proto2:benchmark_message1_proto2_cc_proto",
"//benchmarks/datasets/google_message1/proto3:benchmark_message1_proto3_cc_proto",
"//benchmarks/datasets/google_message2:benchmark_message2_cc_proto",
"//benchmarks/datasets/google_message3:benchmark_message3_cc_proto",
"//benchmarks/datasets/google_message4:benchmark_message4_cc_proto",
],
)
java_library(
name = "java_protos",
visibility = [
"//benchmarks:__subpackages__",
],
exports = [
"//benchmarks/datasets/google_message1/proto2:benchmark_message1_proto2_java_proto",
"//benchmarks/datasets/google_message1/proto3:benchmark_message1_proto3_java_proto",
"//benchmarks/datasets/google_message2:benchmark_message2_java_proto",
"//benchmarks/datasets/google_message3:benchmark_message3_java_proto",
"//benchmarks/datasets/google_message4:benchmark_message4_java_proto",
],
)

@ -0,0 +1,44 @@
load("@rules_cc//cc:defs.bzl", "cc_proto_library")
load("@rules_java//java:defs.bzl", "java_proto_library")
load("@rules_proto//proto:defs.bzl", "proto_library")
filegroup(
name = "datasets",
srcs = [
"dataset.google_message1_proto2.pb",
],
visibility = [
"//benchmarks/datasets:__pkg__",
],
)
proto_library(
name = "benchmark_message1_proto2_proto",
srcs = [
"benchmark_message1_proto2.proto",
],
strip_import_prefix = "/benchmarks",
visibility = [
"//benchmarks/datasets:__pkg__",
],
)
cc_proto_library(
name = "benchmark_message1_proto2_cc_proto",
visibility = [
"//benchmarks/datasets:__pkg__",
],
deps = [
"benchmark_message1_proto2_proto",
],
)
java_proto_library(
name = "benchmark_message1_proto2_java_proto",
visibility = [
"//benchmarks/datasets:__pkg__",
],
deps = [
"benchmark_message1_proto2_proto",
],
)

@ -0,0 +1,44 @@
load("@rules_cc//cc:defs.bzl", "cc_proto_library")
load("@rules_java//java:defs.bzl", "java_proto_library")
load("@rules_proto//proto:defs.bzl", "proto_library")
filegroup(
name = "datasets",
srcs = [
"dataset.google_message1_proto3.pb",
],
visibility = [
"//benchmarks/datasets:__pkg__",
],
)
proto_library(
name = "benchmark_message1_proto3_proto",
srcs = [
"benchmark_message1_proto3.proto",
],
strip_import_prefix = "/benchmarks",
visibility = [
"//benchmarks/datasets:__pkg__",
],
)
cc_proto_library(
name = "benchmark_message1_proto3_cc_proto",
visibility = [
"//benchmarks/datasets:__pkg__",
],
deps = [
"benchmark_message1_proto3_proto",
],
)
java_proto_library(
name = "benchmark_message1_proto3_java_proto",
visibility = [
"//benchmarks/datasets:__pkg__",
],
deps = [
"benchmark_message1_proto3_proto",
],
)

@ -0,0 +1,44 @@
load("@rules_cc//cc:defs.bzl", "cc_proto_library")
load("@rules_java//java:defs.bzl", "java_proto_library")
load("@rules_proto//proto:defs.bzl", "proto_library")
filegroup(
name = "datasets",
srcs = [
"dataset.google_message2.pb",
],
visibility = [
"//benchmarks/datasets:__pkg__",
],
)
proto_library(
name = "benchmark_message2_proto",
srcs = [
"benchmark_message2.proto",
],
strip_import_prefix = "/benchmarks",
visibility = [
"//benchmarks/datasets:__pkg__",
],
)
cc_proto_library(
name = "benchmark_message2_cc_proto",
visibility = [
"//benchmarks/datasets:__pkg__",
],
deps = [
"benchmark_message2_proto",
],
)
java_proto_library(
name = "benchmark_message2_java_proto",
visibility = [
"//benchmarks/datasets:__pkg__",
],
deps = [
"benchmark_message2_proto",
],
)

@ -0,0 +1,50 @@
load("@rules_cc//cc:defs.bzl", "cc_proto_library")
load("@rules_java//java:defs.bzl", "java_proto_library")
load("@rules_proto//proto:defs.bzl", "proto_library")
filegroup(
name = "datasets",
srcs = [],
visibility = [
"//benchmarks/datasets:__pkg__",
],
)
proto_library(
name = "benchmark_message3_proto",
srcs = [
"benchmark_message3.proto",
"benchmark_message3_1.proto",
"benchmark_message3_2.proto",
"benchmark_message3_3.proto",
"benchmark_message3_4.proto",
"benchmark_message3_5.proto",
"benchmark_message3_6.proto",
"benchmark_message3_7.proto",
"benchmark_message3_8.proto",
],
strip_import_prefix = "/benchmarks",
visibility = [
"//benchmarks/datasets:__pkg__",
],
)
cc_proto_library(
name = "benchmark_message3_cc_proto",
visibility = [
"//benchmarks/datasets:__pkg__",
],
deps = [
"benchmark_message3_proto",
],
)
java_proto_library(
name = "benchmark_message3_java_proto",
visibility = [
"//benchmarks/datasets:__pkg__",
],
deps = [
"benchmark_message3_proto",
],
)

@ -0,0 +1,45 @@
load("@rules_cc//cc:defs.bzl", "cc_proto_library")
load("@rules_java//java:defs.bzl", "java_proto_library")
load("@rules_proto//proto:defs.bzl", "proto_library")
filegroup(
name = "datasets",
srcs = [],
visibility = [
"//benchmarks/datasets:__pkg__",
],
)
proto_library(
name = "benchmark_message4_proto",
srcs = [
"benchmark_message4.proto",
"benchmark_message4_1.proto",
"benchmark_message4_2.proto",
"benchmark_message4_3.proto",
],
strip_import_prefix = "/benchmarks",
visibility = [
"//benchmarks/datasets:__pkg__",
],
)
cc_proto_library(
name = "benchmark_message4_cc_proto",
visibility = [
"//benchmarks/datasets:__pkg__",
],
deps = [
"benchmark_message4_proto",
],
)
java_proto_library(
name = "benchmark_message4_java_proto",
visibility = [
"//benchmarks/datasets:__pkg__",
],
deps = [
"benchmark_message4_proto",
],
)

@ -30,7 +30,9 @@ endforeach()
if (protobuf_BUILD_PROTOC_BINARIES)
install(TARGETS protoc EXPORT protobuf-targets
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT protoc)
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
BUNDLE DESTINATION ${CMAKE_INSTALL_BINDIR}
COMPONENT protoc)
if (UNIX AND NOT APPLE)
set_property(TARGET protoc
PROPERTY INSTALL_RPATH "$ORIGIN/../${CMAKE_INSTALL_LIBDIR}")

@ -15,7 +15,7 @@ function(protobuf_generate)
if(COMMAND target_sources)
list(APPEND _singleargs TARGET)
endif()
set(_multiargs PROTOS IMPORT_DIRS GENERATE_EXTENSIONS)
set(_multiargs PROTOS IMPORT_DIRS GENERATE_EXTENSIONS PROTOC_OPTIONS)
cmake_parse_arguments(protobuf_generate "${_options}" "${_singleargs}" "${_multiargs}" "${ARGN}")
@ -130,9 +130,9 @@ function(protobuf_generate)
add_custom_command(
OUTPUT ${_generated_srcs}
COMMAND protobuf::protoc
ARGS --${protobuf_generate_LANGUAGE}_out ${_dll_export_decl}${protobuf_generate_PROTOC_OUT_DIR} ${_plugin} ${_protobuf_include_path} ${_abs_file}
ARGS ${protobuf_generate_PROTOC_OPTIONS} --${protobuf_generate_LANGUAGE}_out ${_dll_export_decl}${protobuf_generate_PROTOC_OUT_DIR} ${_plugin} ${_protobuf_include_path} ${_abs_file}
DEPENDS ${_abs_file} protobuf::protoc
COMMENT "Running ${protobuf_generate_LANGUAGE} protocol buffer compiler on ${_proto}"
COMMENT "Running ${protobuf_generate_LANGUAGE} protocol buffer compiler on ${_proto}. Custom options: ${protobuf_generate_PROTOC_OPTIONS}"
VERBATIM )
endforeach()

@ -223,6 +223,19 @@ case "$target_os" in
esac
AM_CONDITIONAL([OBJC_CONFORMANCE_TEST], [test $OBJC_CONFORMANCE_TEST = 1])
AC_MSG_CHECKING(whether -llog is needed)
ANDROID_TEST=no
case "$target_os" in
*android*)
ANDROID_TEST=yes
;;
esac
AC_MSG_RESULT($ANDROID_TEST)
if test "x$ANDROID_TEST" = xyes; then
LIBLOG_LIBS="-llog"
fi
AC_SUBST([LIBLOG_LIBS])
# HACK: Make gmock's configure script pick up our copy of CFLAGS and CXXFLAGS,
# since the flags added by ACX_CHECK_SUNCC must be used when compiling gmock
# too.

@ -300,7 +300,7 @@ const FieldDescriptor* GetFieldForOneofType(FieldDescriptor::Type type,
}
string UpperCase(string str) {
for (int i = 0; i < str.size(); i++) {
for (size_t i = 0; i < str.size(); i++) {
str[i] = toupper(str[i]);
}
return str;

@ -55,6 +55,7 @@ using google::protobuf::util::JsonToBinaryString;
using google::protobuf::util::NewTypeResolverForDescriptorPool;
using google::protobuf::util::TypeResolver;
using protobuf_test_messages::proto3::TestAllTypesProto3;
using protobuf_test_messages::proto2::TestAllTypesProto2;
using std::string;
static const char kTypeUrlPrefix[] = "type.googleapis.com";
@ -102,6 +103,8 @@ void CheckedWrite(int fd, const void *buf, size_t len) {
void DoTest(const ConformanceRequest& request, ConformanceResponse* response) {
Message *test_message;
google::protobuf::LinkMessageReflection<TestAllTypesProto2>();
google::protobuf::LinkMessageReflection<TestAllTypesProto3>();
const Descriptor *descriptor = DescriptorPool::generated_pool()->FindMessageTypeByName(
request.message_type());
if (!descriptor) {
@ -131,7 +134,7 @@ void DoTest(const ConformanceRequest& request, ConformanceResponse* response) {
&proto_binary, options);
if (!status.ok()) {
response->set_parse_error(string("Parse error: ") +
std::string(status.error_message()));
std::string(status.message()));
return;
}
@ -186,7 +189,7 @@ void DoTest(const ConformanceRequest& request, ConformanceResponse* response) {
if (!status.ok()) {
response->set_serialize_error(
string("Failed to serialize JSON output: ") +
std::string(status.error_message()));
std::string(status.message()));
return;
}
break;

@ -297,7 +297,7 @@ void ForkPipeRunner::SpawnTestProgram() {
std::vector<const char *> argv;
argv.push_back(executable.get());
for (int i = 0; i < executable_args_.size(); ++i) {
for (size_t i = 0; i < executable_args_.size(); ++i) {
argv.push_back(executable_args_[i].c_str());
}
argv.push_back(nullptr);
@ -307,7 +307,7 @@ void ForkPipeRunner::SpawnTestProgram() {
}
void ForkPipeRunner::CheckedWrite(int fd, const void *buf, size_t len) {
if (write(fd, buf, len) != len) {
if (static_cast<size_t>(write(fd, buf, len)) != len) {
GOOGLE_LOG(FATAL) << current_test_name_
<< ": error writing to test program: " << strerror(errno);
}

@ -451,6 +451,27 @@ void TextFormatConformanceTestSuite::RunSuiteImpl() {
}
)",
prototype);
prototype.Clear();
ConformanceRequestSetting setting_map(
REQUIRED, conformance::TEXT_FORMAT, conformance::PROTOBUF,
conformance::TEXT_FORMAT_TEST, prototype, "DuplicateMapKey", R"(
map_string_nested_message {
key: "duplicate"
value: { a: 123 }
}
map_string_nested_message {
key: "duplicate"
value: { corecursive: {} }
}
)");
// The last-specified value will be retained in a parsed map
RunValidInputTest(setting_map, R"(
map_string_nested_message {
key: "duplicate"
value: { corecursive: {} }
}
)");
}
} // namespace protobuf

@ -17,4 +17,4 @@ Invoke-WebRequest -Uri $InstallScriptUrl -OutFile $InstallScriptPath
# The SDK versions to install should be kept in sync with versions
# installed by kokoro/linux/dockerfile/test/csharp/Dockerfile
&$InstallScriptPath -Version 2.1.802
&$InstallScriptPath -Version 3.1.301
&$InstallScriptPath -Version 5.0.102

@ -2,7 +2,7 @@
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp3.1</TargetFramework>
<TargetFramework>net5.0</TargetFramework>
<AssemblyOriginatorKeyFile>../../keys/Google.Protobuf.snk</AssemblyOriginatorKeyFile>
<SignAssembly>true</SignAssembly>
<IsPackable>False</IsPackable>

@ -25,49 +25,54 @@ namespace ProtobufUnittest {
byte[] descriptorData = global::System.Convert.FromBase64String(
string.Concat(
"Ci5nb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfcHJvdG8zX29wdGlvbmFsLnBy",
"b3RvEhFwcm90b2J1Zl91bml0dGVzdCKxCgoSVGVzdFByb3RvM09wdGlvbmFs",
"EhsKDm9wdGlvbmFsX2ludDMyGAEgASgFSACIAQESGwoOb3B0aW9uYWxfaW50",
"NjQYAiABKANIAYgBARIcCg9vcHRpb25hbF91aW50MzIYAyABKA1IAogBARIc",
"Cg9vcHRpb25hbF91aW50NjQYBCABKARIA4gBARIcCg9vcHRpb25hbF9zaW50",
"MzIYBSABKBFIBIgBARIcCg9vcHRpb25hbF9zaW50NjQYBiABKBJIBYgBARId",
"ChBvcHRpb25hbF9maXhlZDMyGAcgASgHSAaIAQESHQoQb3B0aW9uYWxfZml4",
"ZWQ2NBgIIAEoBkgHiAEBEh4KEW9wdGlvbmFsX3NmaXhlZDMyGAkgASgPSAiI",
"AQESHgoRb3B0aW9uYWxfc2ZpeGVkNjQYCiABKBBICYgBARIbCg5vcHRpb25h",
"bF9mbG9hdBgLIAEoAkgKiAEBEhwKD29wdGlvbmFsX2RvdWJsZRgMIAEoAUgL",
"iAEBEhoKDW9wdGlvbmFsX2Jvb2wYDSABKAhIDIgBARIcCg9vcHRpb25hbF9z",
"dHJpbmcYDiABKAlIDYgBARIbCg5vcHRpb25hbF9ieXRlcxgPIAEoDEgOiAEB",
"Eh4KDW9wdGlvbmFsX2NvcmQYECABKAlCAggBSA+IAQESWQoXb3B0aW9uYWxf",
"bmVzdGVkX21lc3NhZ2UYEiABKAsyMy5wcm90b2J1Zl91bml0dGVzdC5UZXN0",
"UHJvdG8zT3B0aW9uYWwuTmVzdGVkTWVzc2FnZUgQiAEBElkKE2xhenlfbmVz",
"dGVkX21lc3NhZ2UYEyABKAsyMy5wcm90b2J1Zl91bml0dGVzdC5UZXN0UHJv",
"dG8zT3B0aW9uYWwuTmVzdGVkTWVzc2FnZUICKAFIEYgBARJTChRvcHRpb25h",
"bF9uZXN0ZWRfZW51bRgVIAEoDjIwLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RQ",
"cm90bzNPcHRpb25hbC5OZXN0ZWRFbnVtSBKIAQESFgoOc2luZ3VsYXJfaW50",
"MzIYFiABKAUSFgoOc2luZ3VsYXJfaW50NjQYFyABKAMaJwoNTmVzdGVkTWVz",
"c2FnZRIPCgJiYhgBIAEoBUgAiAEBQgUKA19iYiJKCgpOZXN0ZWRFbnVtEg8K",
"C1VOU1BFQ0lGSUVEEAASBwoDRk9PEAESBwoDQkFSEAISBwoDQkFaEAMSEAoD",
"TkVHEP///////////wFCEQoPX29wdGlvbmFsX2ludDMyQhEKD19vcHRpb25h",
"bF9pbnQ2NEISChBfb3B0aW9uYWxfdWludDMyQhIKEF9vcHRpb25hbF91aW50",
"NjRCEgoQX29wdGlvbmFsX3NpbnQzMkISChBfb3B0aW9uYWxfc2ludDY0QhMK",
"EV9vcHRpb25hbF9maXhlZDMyQhMKEV9vcHRpb25hbF9maXhlZDY0QhQKEl9v",
"cHRpb25hbF9zZml4ZWQzMkIUChJfb3B0aW9uYWxfc2ZpeGVkNjRCEQoPX29w",
"dGlvbmFsX2Zsb2F0QhIKEF9vcHRpb25hbF9kb3VibGVCEAoOX29wdGlvbmFs",
"X2Jvb2xCEgoQX29wdGlvbmFsX3N0cmluZ0IRCg9fb3B0aW9uYWxfYnl0ZXNC",
"EAoOX29wdGlvbmFsX2NvcmRCGgoYX29wdGlvbmFsX25lc3RlZF9tZXNzYWdl",
"QhYKFF9sYXp5X25lc3RlZF9tZXNzYWdlQhcKFV9vcHRpb25hbF9uZXN0ZWRf",
"ZW51bSKJAgoZVGVzdFByb3RvM09wdGlvbmFsTWVzc2FnZRJSCg5uZXN0ZWRf",
"bWVzc2FnZRgBIAEoCzI6LnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RQcm90bzNP",
"cHRpb25hbE1lc3NhZ2UuTmVzdGVkTWVzc2FnZRJgChdvcHRpb25hbF9uZXN0",
"ZWRfbWVzc2FnZRgCIAEoCzI6LnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RQcm90",
"bzNPcHRpb25hbE1lc3NhZ2UuTmVzdGVkTWVzc2FnZUgAiAEBGhoKDU5lc3Rl",
"ZE1lc3NhZ2USCQoBcxgBIAEoCUIaChhfb3B0aW9uYWxfbmVzdGVkX21lc3Nh",
"Z2VCJQohY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnByb3RvUAFiBnBy",
"b3RvMw=="));
"b3RvEhFwcm90b2J1Zl91bml0dGVzdBogZ29vZ2xlL3Byb3RvYnVmL2Rlc2Ny",
"aXB0b3IucHJvdG8isQoKElRlc3RQcm90bzNPcHRpb25hbBIbCg5vcHRpb25h",
"bF9pbnQzMhgBIAEoBUgAiAEBEhsKDm9wdGlvbmFsX2ludDY0GAIgASgDSAGI",
"AQESHAoPb3B0aW9uYWxfdWludDMyGAMgASgNSAKIAQESHAoPb3B0aW9uYWxf",
"dWludDY0GAQgASgESAOIAQESHAoPb3B0aW9uYWxfc2ludDMyGAUgASgRSASI",
"AQESHAoPb3B0aW9uYWxfc2ludDY0GAYgASgSSAWIAQESHQoQb3B0aW9uYWxf",
"Zml4ZWQzMhgHIAEoB0gGiAEBEh0KEG9wdGlvbmFsX2ZpeGVkNjQYCCABKAZI",
"B4gBARIeChFvcHRpb25hbF9zZml4ZWQzMhgJIAEoD0gIiAEBEh4KEW9wdGlv",
"bmFsX3NmaXhlZDY0GAogASgQSAmIAQESGwoOb3B0aW9uYWxfZmxvYXQYCyAB",
"KAJICogBARIcCg9vcHRpb25hbF9kb3VibGUYDCABKAFIC4gBARIaCg1vcHRp",
"b25hbF9ib29sGA0gASgISAyIAQESHAoPb3B0aW9uYWxfc3RyaW5nGA4gASgJ",
"SA2IAQESGwoOb3B0aW9uYWxfYnl0ZXMYDyABKAxIDogBARIeCg1vcHRpb25h",
"bF9jb3JkGBAgASgJQgIIAUgPiAEBElkKF29wdGlvbmFsX25lc3RlZF9tZXNz",
"YWdlGBIgASgLMjMucHJvdG9idWZfdW5pdHRlc3QuVGVzdFByb3RvM09wdGlv",
"bmFsLk5lc3RlZE1lc3NhZ2VIEIgBARJZChNsYXp5X25lc3RlZF9tZXNzYWdl",
"GBMgASgLMjMucHJvdG9idWZfdW5pdHRlc3QuVGVzdFByb3RvM09wdGlvbmFs",
"Lk5lc3RlZE1lc3NhZ2VCAigBSBGIAQESUwoUb3B0aW9uYWxfbmVzdGVkX2Vu",
"dW0YFSABKA4yMC5wcm90b2J1Zl91bml0dGVzdC5UZXN0UHJvdG8zT3B0aW9u",
"YWwuTmVzdGVkRW51bUgSiAEBEhYKDnNpbmd1bGFyX2ludDMyGBYgASgFEhYK",
"DnNpbmd1bGFyX2ludDY0GBcgASgDGicKDU5lc3RlZE1lc3NhZ2USDwoCYmIY",
"ASABKAVIAIgBAUIFCgNfYmIiSgoKTmVzdGVkRW51bRIPCgtVTlNQRUNJRklF",
"RBAAEgcKA0ZPTxABEgcKA0JBUhACEgcKA0JBWhADEhAKA05FRxD/////////",
"//8BQhEKD19vcHRpb25hbF9pbnQzMkIRCg9fb3B0aW9uYWxfaW50NjRCEgoQ",
"X29wdGlvbmFsX3VpbnQzMkISChBfb3B0aW9uYWxfdWludDY0QhIKEF9vcHRp",
"b25hbF9zaW50MzJCEgoQX29wdGlvbmFsX3NpbnQ2NEITChFfb3B0aW9uYWxf",
"Zml4ZWQzMkITChFfb3B0aW9uYWxfZml4ZWQ2NEIUChJfb3B0aW9uYWxfc2Zp",
"eGVkMzJCFAoSX29wdGlvbmFsX3NmaXhlZDY0QhEKD19vcHRpb25hbF9mbG9h",
"dEISChBfb3B0aW9uYWxfZG91YmxlQhAKDl9vcHRpb25hbF9ib29sQhIKEF9v",
"cHRpb25hbF9zdHJpbmdCEQoPX29wdGlvbmFsX2J5dGVzQhAKDl9vcHRpb25h",
"bF9jb3JkQhoKGF9vcHRpb25hbF9uZXN0ZWRfbWVzc2FnZUIWChRfbGF6eV9u",
"ZXN0ZWRfbWVzc2FnZUIXChVfb3B0aW9uYWxfbmVzdGVkX2VudW0iiQIKGVRl",
"c3RQcm90bzNPcHRpb25hbE1lc3NhZ2USUgoObmVzdGVkX21lc3NhZ2UYASAB",
"KAsyOi5wcm90b2J1Zl91bml0dGVzdC5UZXN0UHJvdG8zT3B0aW9uYWxNZXNz",
"YWdlLk5lc3RlZE1lc3NhZ2USYAoXb3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UY",
"AiABKAsyOi5wcm90b2J1Zl91bml0dGVzdC5UZXN0UHJvdG8zT3B0aW9uYWxN",
"ZXNzYWdlLk5lc3RlZE1lc3NhZ2VIAIgBARoaCg1OZXN0ZWRNZXNzYWdlEgkK",
"AXMYASABKAlCGgoYX29wdGlvbmFsX25lc3RlZF9tZXNzYWdlIqkBChhQcm90",
"bzNPcHRpb25hbEV4dGVuc2lvbnMyPAoPZXh0X25vX29wdGlvbmFsEh8uZ29v",
"Z2xlLnByb3RvYnVmLk1lc3NhZ2VPcHRpb25zGIjN2akBIAEoBTJBChFleHRf",
"d2l0aF9vcHRpb25hbBIfLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3B0aW9u",
"cxiJzdmpASABKAWIAQE6DMDozM0KCMjozM0KEEIlCiFjb20uZ29vZ2xlLnBy",
"b3RvYnVmLnRlc3RpbmcucHJvdG9QAWIGcHJvdG8z"));
descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
new pbr::FileDescriptor[] { },
new pbr::FileDescriptor[] { global::Google.Protobuf.Reflection.DescriptorReflection.Descriptor, },
new pbr::GeneratedClrTypeInfo(null, null, new pbr::GeneratedClrTypeInfo[] {
new pbr::GeneratedClrTypeInfo(typeof(global::ProtobufUnittest.TestProto3Optional), global::ProtobufUnittest.TestProto3Optional.Parser, new[]{ "OptionalInt32", "OptionalInt64", "OptionalUint32", "OptionalUint64", "OptionalSint32", "OptionalSint64", "OptionalFixed32", "OptionalFixed64", "OptionalSfixed32", "OptionalSfixed64", "OptionalFloat", "OptionalDouble", "OptionalBool", "OptionalString", "OptionalBytes", "OptionalCord", "OptionalNestedMessage", "LazyNestedMessage", "OptionalNestedEnum", "SingularInt32", "SingularInt64" }, new[]{ "OptionalInt32", "OptionalInt64", "OptionalUint32", "OptionalUint64", "OptionalSint32", "OptionalSint64", "OptionalFixed32", "OptionalFixed64", "OptionalSfixed32", "OptionalSfixed64", "OptionalFloat", "OptionalDouble", "OptionalBool", "OptionalString", "OptionalBytes", "OptionalCord", "OptionalNestedMessage", "LazyNestedMessage", "OptionalNestedEnum" }, new[]{ typeof(global::ProtobufUnittest.TestProto3Optional.Types.NestedEnum) }, null, new pbr::GeneratedClrTypeInfo[] { new pbr::GeneratedClrTypeInfo(typeof(global::ProtobufUnittest.TestProto3Optional.Types.NestedMessage), global::ProtobufUnittest.TestProto3Optional.Types.NestedMessage.Parser, new[]{ "Bb" }, new[]{ "Bb" }, null, null, null)}),
new pbr::GeneratedClrTypeInfo(typeof(global::ProtobufUnittest.TestProto3OptionalMessage), global::ProtobufUnittest.TestProto3OptionalMessage.Parser, new[]{ "NestedMessage", "OptionalNestedMessage" }, new[]{ "OptionalNestedMessage" }, null, null, new pbr::GeneratedClrTypeInfo[] { new pbr::GeneratedClrTypeInfo(typeof(global::ProtobufUnittest.TestProto3OptionalMessage.Types.NestedMessage), global::ProtobufUnittest.TestProto3OptionalMessage.Types.NestedMessage.Parser, new[]{ "S" }, null, null, null, null)})
new pbr::GeneratedClrTypeInfo(typeof(global::ProtobufUnittest.TestProto3OptionalMessage), global::ProtobufUnittest.TestProto3OptionalMessage.Parser, new[]{ "NestedMessage", "OptionalNestedMessage" }, new[]{ "OptionalNestedMessage" }, null, null, new pbr::GeneratedClrTypeInfo[] { new pbr::GeneratedClrTypeInfo(typeof(global::ProtobufUnittest.TestProto3OptionalMessage.Types.NestedMessage), global::ProtobufUnittest.TestProto3OptionalMessage.Types.NestedMessage.Parser, new[]{ "S" }, null, null, null, null)}),
new pbr::GeneratedClrTypeInfo(typeof(global::ProtobufUnittest.Proto3OptionalExtensions), global::ProtobufUnittest.Proto3OptionalExtensions.Parser, null, null, null, new pb::Extension[] { global::ProtobufUnittest.Proto3OptionalExtensions.Extensions.ExtNoOptional, global::ProtobufUnittest.Proto3OptionalExtensions.Extensions.ExtWithOptional }, null)
}));
}
#endregion
@ -1789,6 +1794,153 @@ namespace ProtobufUnittest {
}
public sealed partial class Proto3OptionalExtensions : pb::IMessage<Proto3OptionalExtensions>
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
, pb::IBufferMessage
#endif
{
private static readonly pb::MessageParser<Proto3OptionalExtensions> _parser = new pb::MessageParser<Proto3OptionalExtensions>(() => new Proto3OptionalExtensions());
private pb::UnknownFieldSet _unknownFields;
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<Proto3OptionalExtensions> Parser { get { return _parser; } }
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pbr::MessageDescriptor Descriptor {
get { return global::ProtobufUnittest.UnittestProto3OptionalReflection.Descriptor.MessageTypes[2]; }
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
pbr::MessageDescriptor pb::IMessage.Descriptor {
get { return Descriptor; }
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public Proto3OptionalExtensions() {
OnConstruction();
}
partial void OnConstruction();
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public Proto3OptionalExtensions(Proto3OptionalExtensions other) : this() {
_unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public Proto3OptionalExtensions Clone() {
return new Proto3OptionalExtensions(this);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override bool Equals(object other) {
return Equals(other as Proto3OptionalExtensions);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public bool Equals(Proto3OptionalExtensions other) {
if (ReferenceEquals(other, null)) {
return false;
}
if (ReferenceEquals(other, this)) {
return true;
}
return Equals(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override int GetHashCode() {
int hash = 1;
if (_unknownFields != null) {
hash ^= _unknownFields.GetHashCode();
}
return hash;
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override string ToString() {
return pb::JsonFormatter.ToDiagnosticString(this);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
output.WriteRawMessage(this);
#else
if (_unknownFields != null) {
_unknownFields.WriteTo(output);
}
#endif
}
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) {
if (_unknownFields != null) {
_unknownFields.WriteTo(ref output);
}
}
#endif
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;
if (_unknownFields != null) {
size += _unknownFields.CalculateSize();
}
return size;
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(Proto3OptionalExtensions other) {
if (other == null) {
return;
}
_unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
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;
}
}
#endif
}
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
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;
}
}
}
#endif
#region Extensions
/// <summary>Container for extensions for other messages declared in the Proto3OptionalExtensions message type.</summary>
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static partial class Extensions {
public static readonly pb::Extension<global::Google.Protobuf.Reflection.MessageOptions, int> ExtNoOptional =
new pb::Extension<global::Google.Protobuf.Reflection.MessageOptions, int>(355886728, pb::FieldCodec.ForInt32(2847093824, 0));
public static readonly pb::Extension<global::Google.Protobuf.Reflection.MessageOptions, int> ExtWithOptional =
new pb::Extension<global::Google.Protobuf.Reflection.MessageOptions, int>(355886729, pb::FieldCodec.ForInt32(2847093832, 0));
}
#endregion
}
#endregion
}

@ -42,7 +42,7 @@ namespace Google.Protobuf.Buffers
/// ArrayBufferWriter is originally from corefx, and has been contributed to Protobuf
/// https://github.com/dotnet/runtime/blob/071da4c41aa808c949a773b92dca6f88de9d11f3/src/libraries/Common/src/System/Buffers/ArrayBufferWriter.cs
/// </summary>
internal sealed class ArrayBufferWriter<T> : IBufferWriter<T>
internal sealed class TestArrayBufferWriter<T> : IBufferWriter<T>
{
private T[] _buffer;
private int _index;
@ -50,10 +50,10 @@ namespace Google.Protobuf.Buffers
private const int DefaultInitialBufferSize = 256;
/// <summary>
/// Creates an instance of an <see cref="ArrayBufferWriter{T}"/>, in which data can be written to,
/// Creates an instance of an <see cref="TestArrayBufferWriter{T}"/>, in which data can be written to,
/// with the default initial capacity.
/// </summary>
public ArrayBufferWriter()
public TestArrayBufferWriter()
{
_buffer = new T[0];
_index = 0;
@ -66,14 +66,14 @@ namespace Google.Protobuf.Buffers
public int? MaxGrowBy { get; set; }
/// <summary>
/// Creates an instance of an <see cref="ArrayBufferWriter{T}"/>, in which data can be written to,
/// Creates an instance of an <see cref="TestArrayBufferWriter{T}"/>, in which data can be written to,
/// with an initial capacity specified.
/// </summary>
/// <param name="initialCapacity">The minimum capacity with which to initialize the underlying buffer.</param>
/// <exception cref="ArgumentException">
/// Thrown when <paramref name="initialCapacity"/> is not positive (i.e. less than or equal to 0).
/// </exception>
public ArrayBufferWriter(int initialCapacity)
public TestArrayBufferWriter(int initialCapacity)
{
if (initialCapacity <= 0)
throw new ArgumentException(nameof(initialCapacity));
@ -111,7 +111,7 @@ namespace Google.Protobuf.Buffers
/// Clears the data written to the underlying buffer.
/// </summary>
/// <remarks>
/// You must clear the <see cref="ArrayBufferWriter{T}"/> before trying to re-use it.
/// You must clear the <see cref="TestArrayBufferWriter{T}"/> before trying to re-use it.
/// </remarks>
public void Clear()
{

@ -58,7 +58,7 @@ namespace Google.Protobuf
Assert.AreEqual(data, rawOutput.ToArray());
// IBufferWriter
var bufferWriter = new ArrayBufferWriter<byte>();
var bufferWriter = new TestArrayBufferWriter<byte>();
WriteContext.Initialize(bufferWriter, out WriteContext ctx);
ctx.WriteUInt32((uint) value);
ctx.Flush();
@ -77,7 +77,7 @@ namespace Google.Protobuf
Assert.AreEqual(data, rawOutput.ToArray());
// IBufferWriter
var bufferWriter = new ArrayBufferWriter<byte>();
var bufferWriter = new TestArrayBufferWriter<byte>();
WriteContext.Initialize(bufferWriter, out WriteContext ctx);
ctx.WriteUInt64(value);
ctx.Flush();
@ -100,7 +100,7 @@ namespace Google.Protobuf
output.Flush();
Assert.AreEqual(data, rawOutput.ToArray());
var bufferWriter = new ArrayBufferWriter<byte>();
var bufferWriter = new TestArrayBufferWriter<byte>();
bufferWriter.MaxGrowBy = bufferSize;
WriteContext.Initialize(bufferWriter, out WriteContext ctx);
ctx.WriteUInt32((uint) value);
@ -115,7 +115,7 @@ namespace Google.Protobuf
output.Flush();
Assert.AreEqual(data, rawOutput.ToArray());
var bufferWriter = new ArrayBufferWriter<byte>();
var bufferWriter = new TestArrayBufferWriter<byte>();
bufferWriter.MaxGrowBy = bufferSize;
WriteContext.Initialize(bufferWriter, out WriteContext ctx);
ctx.WriteUInt64(value);
@ -174,7 +174,7 @@ namespace Google.Protobuf
output.Flush();
Assert.AreEqual(data, rawOutput.ToArray());
var bufferWriter = new ArrayBufferWriter<byte>();
var bufferWriter = new TestArrayBufferWriter<byte>();
WriteContext.Initialize(bufferWriter, out WriteContext ctx);
ctx.WriteFixed32(value);
ctx.Flush();
@ -190,7 +190,7 @@ namespace Google.Protobuf
output.Flush();
Assert.AreEqual(data, rawOutput.ToArray());
var bufferWriter = new ArrayBufferWriter<byte>();
var bufferWriter = new TestArrayBufferWriter<byte>();
bufferWriter.MaxGrowBy = bufferSize;
WriteContext.Initialize(bufferWriter, out WriteContext ctx);
ctx.WriteFixed32(value);
@ -212,7 +212,7 @@ namespace Google.Protobuf
output.Flush();
Assert.AreEqual(data, rawOutput.ToArray());
var bufferWriter = new ArrayBufferWriter<byte>();
var bufferWriter = new TestArrayBufferWriter<byte>();
WriteContext.Initialize(bufferWriter, out WriteContext ctx);
ctx.WriteFixed64(value);
ctx.Flush();
@ -228,7 +228,7 @@ namespace Google.Protobuf
output.Flush();
Assert.AreEqual(data, rawOutput.ToArray());
var bufferWriter = new ArrayBufferWriter<byte>();
var bufferWriter = new TestArrayBufferWriter<byte>();
bufferWriter.MaxGrowBy = blockSize;
WriteContext.Initialize(bufferWriter, out WriteContext ctx);
ctx.WriteFixed64(value);
@ -270,7 +270,7 @@ namespace Google.Protobuf
output.Flush();
Assert.AreEqual(rawBytes, rawOutput.ToArray());
var bufferWriter = new ArrayBufferWriter<byte>();
var bufferWriter = new TestArrayBufferWriter<byte>();
bufferWriter.MaxGrowBy = blockSize;
message.WriteTo(bufferWriter);
Assert.AreEqual(rawBytes, bufferWriter.WrittenSpan.ToArray());
@ -292,7 +292,7 @@ namespace Google.Protobuf
output.Flush();
byte[] expectedBytes2 = expectedOutput.ToArray();
var bufferWriter = new ArrayBufferWriter<byte>();
var bufferWriter = new TestArrayBufferWriter<byte>();
WriteContext.Initialize(bufferWriter, out WriteContext ctx);
ctx.WriteMessage(message);
ctx.Flush();
@ -519,7 +519,21 @@ namespace Google.Protobuf
}
[Test]
public void WriteStringsOfDifferentSizes()
public void WriteString_AsciiSmall_MaxUtf8SizeExceedsBuffer()
{
var buffer = new byte[5];
var output = new CodedOutputStream(buffer);
output.WriteString("ABC");
output.Flush();
// Verify written content
var input = new CodedInputStream(buffer);
Assert.AreEqual("ABC", input.ReadString());
}
[Test]
public void WriteStringsOfDifferentSizes_Ascii()
{
for (int i = 1; i <= 1024; i++)
{
@ -540,5 +554,30 @@ namespace Google.Protobuf
Assert.AreEqual(s, input.ReadString());
}
}
[Test]
public void WriteStringsOfDifferentSizes_Unicode()
{
for (int i = 1; i <= 1024; i++)
{
var buffer = new byte[4096];
var output = new CodedOutputStream(buffer);
var sb = new StringBuilder();
for (int j = 0; j < i; j++)
{
char c = (char)((j % 10) + 10112);
sb.Append(c.ToString()); // incrementing unicode numbers, repeating
}
var s = sb.ToString();
output.WriteString(s);
output.Flush();
// Verify written content
var input = new CodedInputStream(buffer);
Assert.AreEqual(s, input.ReadString());
}
}
}
}

@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net451;netcoreapp2.1</TargetFrameworks>
<TargetFrameworks>net451;netcoreapp2.1;net50</TargetFrameworks>
<AssemblyOriginatorKeyFile>../../keys/Google.Protobuf.snk</AssemblyOriginatorKeyFile>
<SignAssembly>true</SignAssembly>
<IsPackable>False</IsPackable>

@ -551,9 +551,13 @@ namespace Google.Protobuf
}
[Test]
// Skip these test cases in .NET 5 because floating point parsing supports bigger values.
// These big values won't throw an error in the test.
#if !NET5_0
[TestCase("1.7977e308")]
[TestCase("-1.7977e308")]
[TestCase("1e309")]
#endif
[TestCase("1,0")]
[TestCase("1.0.0")]
[TestCase("+1")]

@ -199,8 +199,12 @@ namespace Google.Protobuf
[TestCase("1e-")]
[TestCase("--")]
[TestCase("--1")]
// Skip these test cases in .NET 5 because floating point parsing supports bigger values.
// These big values won't throw an error in the test.
#if !NET5_0
[TestCase("-1.7977e308")]
[TestCase("1.7977e308")]
#endif
public void InvalidNumberValue(string json)
{
AssertThrowsAfter(json);

@ -141,7 +141,7 @@ namespace Google.Protobuf
};
var exception = Assert.Throws<InvalidProtocolBufferException>(() =>
{
WriteContext.Initialize(new ArrayBufferWriter<byte>(), out WriteContext writeCtx);
WriteContext.Initialize(new TestArrayBufferWriter<byte>(), out WriteContext writeCtx);
((IBufferMessage)message).InternalWriteTo(ref writeCtx);
});
Assert.AreEqual($"Message {typeof(LegacyGeneratedCodeMessageA).Name} doesn't provide the generated method that enables WriteContext-based serialization. You might need to regenerate the generated protobuf code.", exception.Message);

@ -83,7 +83,7 @@ namespace Google.Protobuf
var bytes = message.ToByteArray();
// also serialize using IBufferWriter and check it leads to the same data
var bufferWriter = new ArrayBufferWriter<byte>();
var bufferWriter = new TestArrayBufferWriter<byte>();
message.WriteTo(bufferWriter);
Assert.AreEqual(bytes, bufferWriter.WrittenSpan.ToArray(), "Both serialization approaches need to result in the same data.");
@ -112,7 +112,7 @@ namespace Google.Protobuf
Assert.AreEqual(message.CalculateSize(), bytes.Length);
// serialize using IBufferWriter and check it leads to the same output
var bufferWriter = new ArrayBufferWriter<byte>();
var bufferWriter = new TestArrayBufferWriter<byte>();
message.WriteTo(bufferWriter);
Assert.AreEqual(bytes, bufferWriter.WrittenSpan.ToArray());
@ -124,7 +124,7 @@ namespace Google.Protobuf
// test for different IBufferWriter.GetSpan() segment sizes
for (int blockSize = 1; blockSize < 256; blockSize *= 2)
{
var segmentedBufferWriter = new ArrayBufferWriter<byte>();
var segmentedBufferWriter = new TestArrayBufferWriter<byte>();
segmentedBufferWriter.MaxGrowBy = blockSize;
message.WriteTo(segmentedBufferWriter);
Assert.AreEqual(bytes, segmentedBufferWriter.WrittenSpan.ToArray());

@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<Description>C# runtime library for Protocol Buffers - Google's data interchange format.</Description>
@ -8,7 +8,7 @@
<!-- C# 7.2 is required for Span/BufferWriter/ReadOnlySequence -->
<LangVersion>7.2</LangVersion>
<Authors>Google Inc.</Authors>
<TargetFrameworks>netstandard1.1;netstandard2.0;net45</TargetFrameworks>
<TargetFrameworks>netstandard1.1;netstandard2.0;net45;net50</TargetFrameworks>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<AssemblyOriginatorKeyFile>../../keys/Google.Protobuf.snk</AssemblyOriginatorKeyFile>
<SignAssembly>true</SignAssembly>
@ -27,15 +27,23 @@
<DefineConstants>$(DefineConstants);GOOGLE_PROTOBUF_SUPPORT_FAST_STRING</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition=" '$(TargetFramework)' == 'net50' ">
<DefineConstants>$(DefineConstants);GOOGLE_PROTOBUF_SUPPORT_FAST_STRING;GOOGLE_PROTOBUF_SIMD</DefineConstants>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="System.Memory" Version="4.5.3"/>
<PackageReference Include="Microsoft.SourceLink.GitHub" PrivateAssets="All" Version="1.0.0"/>
<!-- Needed for the net45 build to work on Unix. See https://github.com/dotnet/designs/pull/33 -->
<PackageReference Include="Microsoft.NETFramework.ReferenceAssemblies" PrivateAssets="All" Version="1.0.0"/>
</ItemGroup>
<!-- Needed for netcoreapp2.1 to work correctly. .NET is not able to load the assembly without this -->
<ItemGroup Condition=" '$(TargetFramework)' == 'net45' OR '$(TargetFramework)' == 'netstandard1.1' ">
<PackageReference Include="System.Memory" Version="4.5.3"/>
</ItemGroup>
<ItemGroup Condition=" '$(TargetFramework)' == 'netstandard2.0' ">
<PackageReference Include="System.Memory" Version="4.5.3"/>
<!-- Needed for netcoreapp2.1 to work correctly. .NET is not able to load the assembly without this -->
<PackageReference Include="System.Runtime.CompilerServices.Unsafe" Version="4.5.2"/>
</ItemGroup>

@ -107,57 +107,58 @@ namespace Google.Protobuf.Reflection {
"eV9wYWNrYWdlGC0gASgJEkMKFHVuaW50ZXJwcmV0ZWRfb3B0aW9uGOcHIAMo",
"CzIkLmdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uIjoKDE9w",
"dGltaXplTW9kZRIJCgVTUEVFRBABEg0KCUNPREVfU0laRRACEhAKDExJVEVf",
"UlVOVElNRRADKgkI6AcQgICAgAJKBAgmECci8gEKDk1lc3NhZ2VPcHRpb25z",
"UlVOVElNRRADKgkI6AcQgICAgAJKBAgmECcihAIKDk1lc3NhZ2VPcHRpb25z",
"EiYKF21lc3NhZ2Vfc2V0X3dpcmVfZm9ybWF0GAEgASgIOgVmYWxzZRIuCh9u",
"b19zdGFuZGFyZF9kZXNjcmlwdG9yX2FjY2Vzc29yGAIgASgIOgVmYWxzZRIZ",
"CgpkZXByZWNhdGVkGAMgASgIOgVmYWxzZRIRCgltYXBfZW50cnkYByABKAgS",
"QwoUdW5pbnRlcnByZXRlZF9vcHRpb24Y5wcgAygLMiQuZ29vZ2xlLnByb3Rv",
"YnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24qCQjoBxCAgICAAkoECAgQCUoECAkQ",
"CiKeAwoMRmllbGRPcHRpb25zEjoKBWN0eXBlGAEgASgOMiMuZ29vZ2xlLnBy",
"b3RvYnVmLkZpZWxkT3B0aW9ucy5DVHlwZToGU1RSSU5HEg4KBnBhY2tlZBgC",
"IAEoCBI/CgZqc3R5cGUYBiABKA4yJC5nb29nbGUucHJvdG9idWYuRmllbGRP",
"cHRpb25zLkpTVHlwZToJSlNfTk9STUFMEhMKBGxhenkYBSABKAg6BWZhbHNl",
"EhkKCmRlcHJlY2F0ZWQYAyABKAg6BWZhbHNlEhMKBHdlYWsYCiABKAg6BWZh",
"bHNlEkMKFHVuaW50ZXJwcmV0ZWRfb3B0aW9uGOcHIAMoCzIkLmdvb2dsZS5w",
"cm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uIi8KBUNUeXBlEgoKBlNUUklO",
"RxAAEggKBENPUkQQARIQCgxTVFJJTkdfUElFQ0UQAiI1CgZKU1R5cGUSDQoJ",
"SlNfTk9STUFMEAASDQoJSlNfU1RSSU5HEAESDQoJSlNfTlVNQkVSEAIqCQjo",
"BxCAgICAAkoECAQQBSJeCgxPbmVvZk9wdGlvbnMSQwoUdW5pbnRlcnByZXRl",
"ZF9vcHRpb24Y5wcgAygLMiQuZ29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0",
"ZWRPcHRpb24qCQjoBxCAgICAAiKTAQoLRW51bU9wdGlvbnMSEwoLYWxsb3df",
"YWxpYXMYAiABKAgSGQoKZGVwcmVjYXRlZBgDIAEoCDoFZmFsc2USQwoUdW5p",
"bnRlcnByZXRlZF9vcHRpb24Y5wcgAygLMiQuZ29vZ2xlLnByb3RvYnVmLlVu",
"aW50ZXJwcmV0ZWRPcHRpb24qCQjoBxCAgICAAkoECAUQBiJ9ChBFbnVtVmFs",
"dWVPcHRpb25zEhkKCmRlcHJlY2F0ZWQYASABKAg6BWZhbHNlEkMKFHVuaW50",
"ZXJwcmV0ZWRfb3B0aW9uGOcHIAMoCzIkLmdvb2dsZS5wcm90b2J1Zi5Vbmlu",
"dGVycHJldGVkT3B0aW9uKgkI6AcQgICAgAIiewoOU2VydmljZU9wdGlvbnMS",
"GQoKZGVwcmVjYXRlZBghIAEoCDoFZmFsc2USQwoUdW5pbnRlcnByZXRlZF9v",
"cHRpb24Y5wcgAygLMiQuZ29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRP",
"cHRpb24qCQjoBxCAgICAAiKtAgoNTWV0aG9kT3B0aW9ucxIZCgpkZXByZWNh",
"dGVkGCEgASgIOgVmYWxzZRJfChFpZGVtcG90ZW5jeV9sZXZlbBgiIAEoDjIv",
"Lmdvb2dsZS5wcm90b2J1Zi5NZXRob2RPcHRpb25zLklkZW1wb3RlbmN5TGV2",
"ZWw6E0lERU1QT1RFTkNZX1VOS05PV04SQwoUdW5pbnRlcnByZXRlZF9vcHRp",
"b24Y5wcgAygLMiQuZ29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRp",
"b24iUAoQSWRlbXBvdGVuY3lMZXZlbBIXChNJREVNUE9URU5DWV9VTktOT1dO",
"EAASEwoPTk9fU0lERV9FRkZFQ1RTEAESDgoKSURFTVBPVEVOVBACKgkI6AcQ",
"gICAgAIingIKE1VuaW50ZXJwcmV0ZWRPcHRpb24SOwoEbmFtZRgCIAMoCzIt",
"Lmdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uLk5hbWVQYXJ0",
"EhgKEGlkZW50aWZpZXJfdmFsdWUYAyABKAkSGgoScG9zaXRpdmVfaW50X3Zh",
"bHVlGAQgASgEEhoKEm5lZ2F0aXZlX2ludF92YWx1ZRgFIAEoAxIUCgxkb3Vi",
"bGVfdmFsdWUYBiABKAESFAoMc3RyaW5nX3ZhbHVlGAcgASgMEhcKD2FnZ3Jl",
"Z2F0ZV92YWx1ZRgIIAEoCRozCghOYW1lUGFydBIRCgluYW1lX3BhcnQYASAC",
"KAkSFAoMaXNfZXh0ZW5zaW9uGAIgAigIItUBCg5Tb3VyY2VDb2RlSW5mbxI6",
"Cghsb2NhdGlvbhgBIAMoCzIoLmdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb2Rl",
"SW5mby5Mb2NhdGlvbhqGAQoITG9jYXRpb24SEAoEcGF0aBgBIAMoBUICEAES",
"EAoEc3BhbhgCIAMoBUICEAESGAoQbGVhZGluZ19jb21tZW50cxgDIAEoCRIZ",
"ChF0cmFpbGluZ19jb21tZW50cxgEIAEoCRIhChlsZWFkaW5nX2RldGFjaGVk",
"X2NvbW1lbnRzGAYgAygJIqcBChFHZW5lcmF0ZWRDb2RlSW5mbxJBCgphbm5v",
"dGF0aW9uGAEgAygLMi0uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZENvZGVJ",
"bmZvLkFubm90YXRpb24aTwoKQW5ub3RhdGlvbhIQCgRwYXRoGAEgAygFQgIQ",
"ARITCgtzb3VyY2VfZmlsZRgCIAEoCRINCgViZWdpbhgDIAEoBRILCgNlbmQY",
"BCABKAVCfgoTY29tLmdvb2dsZS5wcm90b2J1ZkIQRGVzY3JpcHRvclByb3Rv",
"c0gBWi1nb29nbGUuZ29sYW5nLm9yZy9wcm90b2J1Zi90eXBlcy9kZXNjcmlw",
"dG9ycGL4AQGiAgNHUEKqAhpHb29nbGUuUHJvdG9idWYuUmVmbGVjdGlvbg=="));
"YnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24qCQjoBxCAgICAAkoECAQQBUoECAUQ",
"BkoECAYQB0oECAgQCUoECAkQCiKeAwoMRmllbGRPcHRpb25zEjoKBWN0eXBl",
"GAEgASgOMiMuZ29vZ2xlLnByb3RvYnVmLkZpZWxkT3B0aW9ucy5DVHlwZToG",
"U1RSSU5HEg4KBnBhY2tlZBgCIAEoCBI/CgZqc3R5cGUYBiABKA4yJC5nb29n",
"bGUucHJvdG9idWYuRmllbGRPcHRpb25zLkpTVHlwZToJSlNfTk9STUFMEhMK",
"BGxhenkYBSABKAg6BWZhbHNlEhkKCmRlcHJlY2F0ZWQYAyABKAg6BWZhbHNl",
"EhMKBHdlYWsYCiABKAg6BWZhbHNlEkMKFHVuaW50ZXJwcmV0ZWRfb3B0aW9u",
"GOcHIAMoCzIkLmdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9u",
"Ii8KBUNUeXBlEgoKBlNUUklORxAAEggKBENPUkQQARIQCgxTVFJJTkdfUElF",
"Q0UQAiI1CgZKU1R5cGUSDQoJSlNfTk9STUFMEAASDQoJSlNfU1RSSU5HEAES",
"DQoJSlNfTlVNQkVSEAIqCQjoBxCAgICAAkoECAQQBSJeCgxPbmVvZk9wdGlv",
"bnMSQwoUdW5pbnRlcnByZXRlZF9vcHRpb24Y5wcgAygLMiQuZ29vZ2xlLnBy",
"b3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24qCQjoBxCAgICAAiKTAQoLRW51",
"bU9wdGlvbnMSEwoLYWxsb3dfYWxpYXMYAiABKAgSGQoKZGVwcmVjYXRlZBgD",
"IAEoCDoFZmFsc2USQwoUdW5pbnRlcnByZXRlZF9vcHRpb24Y5wcgAygLMiQu",
"Z29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24qCQjoBxCAgICA",
"AkoECAUQBiJ9ChBFbnVtVmFsdWVPcHRpb25zEhkKCmRlcHJlY2F0ZWQYASAB",
"KAg6BWZhbHNlEkMKFHVuaW50ZXJwcmV0ZWRfb3B0aW9uGOcHIAMoCzIkLmdv",
"b2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uKgkI6AcQgICAgAIi",
"ewoOU2VydmljZU9wdGlvbnMSGQoKZGVwcmVjYXRlZBghIAEoCDoFZmFsc2US",
"QwoUdW5pbnRlcnByZXRlZF9vcHRpb24Y5wcgAygLMiQuZ29vZ2xlLnByb3Rv",
"YnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24qCQjoBxCAgICAAiKtAgoNTWV0aG9k",
"T3B0aW9ucxIZCgpkZXByZWNhdGVkGCEgASgIOgVmYWxzZRJfChFpZGVtcG90",
"ZW5jeV9sZXZlbBgiIAEoDjIvLmdvb2dsZS5wcm90b2J1Zi5NZXRob2RPcHRp",
"b25zLklkZW1wb3RlbmN5TGV2ZWw6E0lERU1QT1RFTkNZX1VOS05PV04SQwoU",
"dW5pbnRlcnByZXRlZF9vcHRpb24Y5wcgAygLMiQuZ29vZ2xlLnByb3RvYnVm",
"LlVuaW50ZXJwcmV0ZWRPcHRpb24iUAoQSWRlbXBvdGVuY3lMZXZlbBIXChNJ",
"REVNUE9URU5DWV9VTktOT1dOEAASEwoPTk9fU0lERV9FRkZFQ1RTEAESDgoK",
"SURFTVBPVEVOVBACKgkI6AcQgICAgAIingIKE1VuaW50ZXJwcmV0ZWRPcHRp",
"b24SOwoEbmFtZRgCIAMoCzItLmdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJl",
"dGVkT3B0aW9uLk5hbWVQYXJ0EhgKEGlkZW50aWZpZXJfdmFsdWUYAyABKAkS",
"GgoScG9zaXRpdmVfaW50X3ZhbHVlGAQgASgEEhoKEm5lZ2F0aXZlX2ludF92",
"YWx1ZRgFIAEoAxIUCgxkb3VibGVfdmFsdWUYBiABKAESFAoMc3RyaW5nX3Zh",
"bHVlGAcgASgMEhcKD2FnZ3JlZ2F0ZV92YWx1ZRgIIAEoCRozCghOYW1lUGFy",
"dBIRCgluYW1lX3BhcnQYASACKAkSFAoMaXNfZXh0ZW5zaW9uGAIgAigIItUB",
"Cg5Tb3VyY2VDb2RlSW5mbxI6Cghsb2NhdGlvbhgBIAMoCzIoLmdvb2dsZS5w",
"cm90b2J1Zi5Tb3VyY2VDb2RlSW5mby5Mb2NhdGlvbhqGAQoITG9jYXRpb24S",
"EAoEcGF0aBgBIAMoBUICEAESEAoEc3BhbhgCIAMoBUICEAESGAoQbGVhZGlu",
"Z19jb21tZW50cxgDIAEoCRIZChF0cmFpbGluZ19jb21tZW50cxgEIAEoCRIh",
"ChlsZWFkaW5nX2RldGFjaGVkX2NvbW1lbnRzGAYgAygJIqcBChFHZW5lcmF0",
"ZWRDb2RlSW5mbxJBCgphbm5vdGF0aW9uGAEgAygLMi0uZ29vZ2xlLnByb3Rv",
"YnVmLkdlbmVyYXRlZENvZGVJbmZvLkFubm90YXRpb24aTwoKQW5ub3RhdGlv",
"bhIQCgRwYXRoGAEgAygFQgIQARITCgtzb3VyY2VfZmlsZRgCIAEoCRINCgVi",
"ZWdpbhgDIAEoBRILCgNlbmQYBCABKAVCfgoTY29tLmdvb2dsZS5wcm90b2J1",
"ZkIQRGVzY3JpcHRvclByb3Rvc0gBWi1nb29nbGUuZ29sYW5nLm9yZy9wcm90",
"b2J1Zi90eXBlcy9kZXNjcmlwdG9ycGL4AQGiAgNHUEKqAhpHb29nbGUuUHJv",
"dG9idWYuUmVmbGVjdGlvbg=="));
descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
new pbr::FileDescriptor[] { },
new pbr::GeneratedClrTypeInfo(null, null, new pbr::GeneratedClrTypeInfo[] {
@ -4795,11 +4796,11 @@ namespace Google.Protobuf.Reflection {
private string javaOuterClassname_;
/// <summary>
/// If set, all the classes from the .proto file are wrapped in a single
/// outer class with the given name. This applies to both Proto1
/// (equivalent to the old "--one_java_file" option) and Proto2 (where
/// a .proto always translates to a single class, but you may want to
/// explicitly choose the class name).
/// Controls the name of the wrapper Java class generated for the .proto file.
/// That class will always contain the .proto file's getDescriptor() method as
/// well as any top-level extensions defined in the .proto file.
/// If java_multiple_files is disabled, then all the other classes from the
/// .proto file will be nested inside the single wrapper outer class.
/// </summary>
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public string JavaOuterClassname {
@ -4825,10 +4826,10 @@ namespace Google.Protobuf.Reflection {
private bool javaMultipleFiles_;
/// <summary>
/// If set true, then the Java code generator will generate a separate .java
/// If enabled, then the Java code generator will generate a separate .java
/// file for each top-level message, enum, and service defined in the .proto
/// file. Thus, these types will *not* be nested inside the outer class
/// named by java_outer_classname. However, the outer class will still be
/// file. Thus, these types will *not* be nested inside the wrapper class
/// named by java_outer_classname. However, the wrapper class will still be
/// generated to contain the file's getDescriptor() method as well as any
/// top-level extensions defined in the file.
/// </summary>

@ -32,8 +32,14 @@
using System;
using System.Buffers.Binary;
using System.Diagnostics;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
#if GOOGLE_PROTOBUF_SIMD
using System.Runtime.Intrinsics;
using System.Runtime.Intrinsics.Arm;
using System.Runtime.Intrinsics.X86;
#endif
using System.Security;
using System.Text;
@ -45,8 +51,11 @@ namespace Google.Protobuf
[SecuritySafeCritical]
internal static class WritingPrimitives
{
// "Local" copy of Encoding.UTF8, for efficiency. (Yes, it makes a difference.)
internal static readonly Encoding Utf8Encoding = Encoding.UTF8;
#if NET5_0
internal static Encoding Utf8Encoding => Encoding.UTF8; // allows JIT to devirtualize
#else
internal static readonly Encoding Utf8Encoding = Encoding.UTF8; // "Local" copy of Encoding.UTF8, for efficiency. (Yes, it makes a difference.)
#endif
#region Writing of values (not including tags)
@ -186,11 +195,7 @@ namespace Google.Protobuf
{
if (length == value.Length) // Must be all ASCII...
{
for (int i = 0; i < length; i++)
{
buffer[state.position + i] = (byte)value[i];
}
state.position += length;
WriteAsciiStringToBuffer(buffer, ref state, value, length);
}
else
{
@ -208,6 +213,104 @@ namespace Google.Protobuf
}
}
// Calling this method with non-ASCII content will break.
// Content must be verified to be all ASCII before using this method.
private static void WriteAsciiStringToBuffer(Span<byte> buffer, ref WriterInternalState state, string value, int length)
{
ref char sourceChars = ref MemoryMarshal.GetReference(value.AsSpan());
ref byte destinationBytes = ref MemoryMarshal.GetReference(buffer.Slice(state.position));
int currentIndex = 0;
// If 64bit, process 4 chars at a time.
// The logic inside this check will be elided by JIT in 32bit programs.
if (IntPtr.Size == 8)
{
// Need at least 4 chars available to use this optimization.
if (length >= 4)
{
ref byte sourceBytes = ref Unsafe.As<char, byte>(ref sourceChars);
// Process 4 chars at a time until there are less than 4 remaining.
// We already know all characters are ASCII so there is no need to validate the source.
int lastIndexWhereCanReadFourChars = value.Length - 4;
do
{
NarrowFourUtf16CharsToAsciiAndWriteToBuffer(
ref Unsafe.AddByteOffset(ref destinationBytes, (IntPtr)currentIndex),
Unsafe.ReadUnaligned<ulong>(ref Unsafe.AddByteOffset(ref sourceBytes, (IntPtr)(currentIndex * 2))));
} while ((currentIndex += 4) <= lastIndexWhereCanReadFourChars);
}
}
// Process any remaining, 1 char at a time.
// Avoid bounds checking with ref + Unsafe
for (; currentIndex < length; currentIndex++)
{
Unsafe.AddByteOffset(ref destinationBytes, (IntPtr)currentIndex) = (byte)Unsafe.AddByteOffset(ref sourceChars, (IntPtr)(currentIndex * 2));
}
state.position += length;
}
// Copied with permission from https://github.com/dotnet/runtime/blob/1cdafd27e4afd2c916af5df949c13f8b373c4335/src/libraries/System.Private.CoreLib/src/System/Text/ASCIIUtility.cs#L1119-L1171
//
/// <summary>
/// Given a QWORD which represents a buffer of 4 ASCII chars in machine-endian order,
/// narrows each WORD to a BYTE, then writes the 4-byte result to the output buffer
/// also in machine-endian order.
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static void NarrowFourUtf16CharsToAsciiAndWriteToBuffer(ref byte outputBuffer, ulong value)
{
#if GOOGLE_PROTOBUF_SIMD
if (Sse2.X64.IsSupported)
{
// Narrows a vector of words [ w0 w1 w2 w3 ] to a vector of bytes
// [ b0 b1 b2 b3 b0 b1 b2 b3 ], then writes 4 bytes (32 bits) to the destination.
Vector128<short> vecWide = Sse2.X64.ConvertScalarToVector128UInt64(value).AsInt16();
Vector128<uint> vecNarrow = Sse2.PackUnsignedSaturate(vecWide, vecWide).AsUInt32();
Unsafe.WriteUnaligned<uint>(ref outputBuffer, Sse2.ConvertToUInt32(vecNarrow));
}
else if (AdvSimd.IsSupported)
{
// Narrows a vector of words [ w0 w1 w2 w3 ] to a vector of bytes
// [ b0 b1 b2 b3 * * * * ], then writes 4 bytes (32 bits) to the destination.
Vector128<short> vecWide = Vector128.CreateScalarUnsafe(value).AsInt16();
Vector64<byte> lower = AdvSimd.ExtractNarrowingSaturateUnsignedLower(vecWide);
Unsafe.WriteUnaligned<uint>(ref outputBuffer, lower.AsUInt32().ToScalar());
}
else
#endif
{
// Fallback to non-SIMD approach when SIMD is not available.
// This could happen either because the APIs are not available, or hardware doesn't support it.
// Processing 4 chars at a time in this fallback is still faster than casting one char at a time.
if (BitConverter.IsLittleEndian)
{
outputBuffer = (byte)value;
value >>= 16;
Unsafe.Add(ref outputBuffer, 1) = (byte)value;
value >>= 16;
Unsafe.Add(ref outputBuffer, 2) = (byte)value;
value >>= 16;
Unsafe.Add(ref outputBuffer, 3) = (byte)value;
}
else
{
Unsafe.Add(ref outputBuffer, 3) = (byte)value;
value >>= 16;
Unsafe.Add(ref outputBuffer, 2) = (byte)value;
value >>= 16;
Unsafe.Add(ref outputBuffer, 1) = (byte)value;
value >>= 16;
outputBuffer = (byte)value;
}
}
}
private static int WriteStringToBuffer(Span<byte> buffer, ref WriterInternalState state, string value)
{
#if NETSTANDARD1_1

@ -261,7 +261,7 @@ bool FieldHasPresence(const google::protobuf::FieldDescriptor* field) {
Old:
```c++
bool FieldIsInOneof(const google::protobuf::FielDescriptor* field) {
bool FieldIsInOneof(const google::protobuf::FieldDescriptor* field) {
return field->containing_oneof() != nullptr;
}
```
@ -269,7 +269,7 @@ bool FieldIsInOneof(const google::protobuf::FielDescriptor* field) {
New:
```c++
bool FieldIsInOneof(const google::protobuf::FielDescriptor* field) {
bool FieldIsInOneof(const google::protobuf::FieldDescriptor* field) {
// real_containing_oneof() returns nullptr for synthetic oneofs.
return field->real_containing_oneof() != nullptr;
}

@ -0,0 +1,18 @@
# Ahead Of Time (AOT) compilation for the Java Virtual Machine (JVM)"
Ahead Of Time (AOT) compilation build tools such as those provided by [GraalVM's `native-image`](https://www.graalvm.org/reference-manual/native-image/) can require some configuration when using protobuf.
Protobuf for the JVM uses reflection and some of its target classes are not possible to determine in advance.
Historically, there were good reasons to use reflection based on APIs that were published effectively requiring them, and this situation is unlikely to change.
[The Lite version of protobuf for the JVM](https://github.com/protocolbuffers/protobuf/blob/master/java/lite.md)
avoids reflection and may be better suited for use with AOT compilation tooling. This Lite version was originally targeted for use on Android which has similar AOT compilation
goals as GraalVM's native-image tool.
## GraalVM native-image
This section addresses GraalVM's `native-image` configuration specifically as this AOT compilation tool due to its popularity. The `native-image` tool can be configured
with respect to: the [Java Native Interface](https://en.wikipedia.org/wiki/Java_Native_Interface) (JNI), http proxying, reflection, and other resources. While these
considerations can be manually declared as JSON files, we recommend that a JVM application is exercised along with
[the assisted configuration agent](https://www.graalvm.org/reference-manual/native-image/BuildConfiguration/#assisted-configuration-of-native-image-builds). The agent
will generate files that you can then subsequently point at when invoking `native-image`. We recommend that the generated files are retained with a project's source
code.

@ -263,8 +263,16 @@ with info about your project (name and website) so we can add an entry for you.
1. Protoc-gen-psql
* Website: https://github.com/Intrinsec/protoc-gen-psql
* Extension: 1091
* Extension: 1091-1101
1. Protoc-gen-sanitize
* Website: https://github.com/Intrinsec/protoc-gen-sanitize
* Extension: 1092
* Extension: 1102-1106
1. Coach Client Connect (planned release in March 2021)
* Website: https://www.coachclientconnect.com
* Extension: 1107
1. Kratos API Errors
* Website: https://go-kratos.dev
* Extension: 1108

@ -11,6 +11,7 @@ These are projects we know about implementing Protocol Buffers for other program
* Action Script: https://code.google.com/p/protoc-gen-as3/
* Action Script: https://github.com/matrix3d/JProtoc
* Action Script: https://github.com/zhongfq/protobuf-as3/
* Ada: https://github.com/reznikmm/protobuf
* C: https://github.com/protobuf-c/protobuf-c
* C: http://koti.kapsi.fi/jpa/nanopb/
* C: https://github.com/cloudwu/pbc/
@ -101,7 +102,6 @@ These are projects we know about implementing Protocol Buffers for other program
* Solidity: https://github.com/celer-network/pb3-gen-sol
* Swift: https://github.com/alexeyxo/protobuf-swift
* Swift: https://github.com/apple/swift-protobuf/
* Typescript: https://github.com/y3llowcake/protoc-gen-ts
* Vala: https://launchpad.net/protobuf-vala
* Visual Basic: http://code.google.com/p/protobuf-net/

@ -1,6 +1,6 @@
{
"sdk": {
"version": "3.0.100",
"version": "5.0.102",
"rollForward": "latestMinor"
}
}

@ -23,7 +23,7 @@ If you are using Maven, use the following:
<dependency>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-java</artifactId>
<version>3.11.0</version>
<version>3.15.3</version>
</dependency>
```
@ -37,7 +37,7 @@ protobuf-java-util package:
<dependency>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-java-util</artifactId>
<version>3.11.0</version>
<version>3.15.3</version>
</dependency>
```

@ -85,6 +85,7 @@ LITE_SRCS = [
"src/main/java/com/google/protobuf/UnknownFieldSetLite.java",
"src/main/java/com/google/protobuf/UnknownFieldSetLiteSchema.java",
"src/main/java/com/google/protobuf/UnmodifiableLazyStringList.java",
"src/main/java/com/google/protobuf/UnsafeByteOperations.java",
"src/main/java/com/google/protobuf/UnsafeUtil.java",
"src/main/java/com/google/protobuf/Utf8.java",
"src/main/java/com/google/protobuf/WireFormat.java",

@ -1043,8 +1043,10 @@ public abstract class ByteString implements Iterable<Byte>, Serializable {
}
/**
* Creates a byte string. Its size is the current size of this output stream and its output has
* been copied to it.
* Creates a byte string with the size and contents of this output stream. This does not create
* a new copy of the underlying bytes. If the stream size grows dynamically, the runtime is
* O(log n) in respect to the number of bytes written to the {@link Output}. If the stream size
* stays within the initial capacity, the runtime is O(1).
*
* @return the current contents of this output stream, as a byte string.
*/

@ -1185,6 +1185,9 @@ public abstract class CodedInputStream {
throw InvalidProtocolBufferException.negativeSize();
}
byteLimit += getTotalBytesRead();
if (byteLimit < 0) {
throw InvalidProtocolBufferException.parseFailure();
}
final int oldLimit = currentLimit;
if (byteLimit > oldLimit) {
throw InvalidProtocolBufferException.truncatedMessage();
@ -2055,6 +2058,44 @@ public abstract class CodedInputStream {
totalBytesRetired = 0;
}
/*
* The following wrapper methods exist so that InvalidProtocolBufferExceptions thrown by the
* InputStream can be differentiated from ones thrown by CodedInputStream itself. Each call to
* an InputStream method that can throw IOException must be wrapped like this. We do this
* because we sometimes need to modify IPBE instances after they are thrown far away from where
* they are thrown (ex. to add unfinished messages) and we use this signal elsewhere in the
* exception catch chain to know when to perform these operations directly or to wrap the
* exception in their own IPBE so the extra information can be communicated without trampling
* downstream information.
*/
private static int read(InputStream input, byte[] data, int offset, int length)
throws IOException {
try {
return input.read(data, offset, length);
} catch (InvalidProtocolBufferException e) {
e.setThrownFromInputStream();
throw e;
}
}
private static long skip(InputStream input, long length) throws IOException {
try {
return input.skip(length);
} catch (InvalidProtocolBufferException e) {
e.setThrownFromInputStream();
throw e;
}
}
private static int available(InputStream input) throws IOException {
try {
return input.available();
} catch (InvalidProtocolBufferException e) {
e.setThrownFromInputStream();
throw e;
}
}
@Override
public int readTag() throws IOException {
if (isAtEnd()) {
@ -2783,7 +2824,8 @@ public abstract class CodedInputStream {
// Here we should refill the buffer as many bytes as possible.
int bytesRead =
input.read(
read(
input,
buffer,
bufferSize,
Math.min(
@ -2905,7 +2947,7 @@ public abstract class CodedInputStream {
// Determine the number of bytes we need to read from the input stream.
int sizeLeft = size - bufferedBytes;
// TODO(nathanmittler): Consider using a value larger than DEFAULT_BUFFER_SIZE.
if (sizeLeft < DEFAULT_BUFFER_SIZE || sizeLeft <= input.available()) {
if (sizeLeft < DEFAULT_BUFFER_SIZE || sizeLeft <= available(input)) {
// Either the bytes we need are known to be available, or the required buffer is
// within an allowed threshold - go ahead and allocate the buffer now.
final byte[] bytes = new byte[size];
@ -2919,7 +2961,7 @@ public abstract class CodedInputStream {
// Fill the remaining bytes from the input stream.
int tempPos = bufferedBytes;
while (tempPos < bytes.length) {
int n = input.read(bytes, tempPos, size - tempPos);
int n = read(input, bytes, tempPos, size - tempPos);
if (n == -1) {
throw InvalidProtocolBufferException.truncatedMessage();
}
@ -3047,7 +3089,7 @@ public abstract class CodedInputStream {
try {
while (totalSkipped < size) {
int toSkip = size - totalSkipped;
long skipped = input.skip(toSkip);
long skipped = skip(input, toSkip);
if (skipped < 0 || skipped > toSkip) {
throw new IllegalStateException(
input.getClass()
@ -3484,9 +3526,25 @@ public abstract class CodedInputStream {
return ByteString.wrap(bytes);
}
} else if (size > 0 && size <= remaining()) {
byte[] temp = new byte[size];
readRawBytesTo(temp, 0, size);
return ByteString.wrap(temp);
if (immutable && enableAliasing) {
ArrayList<ByteString> byteStrings = new ArrayList<>();
int l = size;
while (l > 0) {
if (currentRemaining() == 0) {
getNextByteBuffer();
}
int bytesToCopy = Math.min(l, (int) currentRemaining());
int idx = (int) (currentByteBufferPos - currentAddress);
byteStrings.add(ByteString.wrap(slice(idx, idx + bytesToCopy)));
l -= bytesToCopy;
currentByteBufferPos += bytesToCopy;
}
return ByteString.copyFrom(byteStrings);
} else {
byte[] temp = new byte[size];
readRawBytesTo(temp, 0, size);
return ByteString.wrap(temp);
}
}
if (size == 0) {

@ -282,7 +282,7 @@ final class FieldSet<T extends FieldSet.FieldDescriptorLite<T>> {
// Wrap the contents in a new list so that the caller cannot change
// the list's contents after setting it.
final List newList = new ArrayList();
final List newList = new ArrayList<>();
newList.addAll((List) value);
for (final Object element : newList) {
verifyType(descriptor, element);

@ -1537,11 +1537,16 @@ public abstract class GeneratedMessageLite<
Schema<T> schema = Protobuf.getInstance().schemaFor(result);
schema.mergeFrom(result, CodedInputStreamReader.forCodedInput(input), extensionRegistry);
schema.makeImmutable(result);
} catch (InvalidProtocolBufferException e) {
if (e.getThrownFromInputStream()) {
e = new InvalidProtocolBufferException(e);
}
throw e.setUnfinishedMessage(result);
} catch (IOException e) {
if (e.getCause() instanceof InvalidProtocolBufferException) {
throw (InvalidProtocolBufferException) e.getCause();
}
throw new InvalidProtocolBufferException(e.getMessage()).setUnfinishedMessage(result);
throw new InvalidProtocolBufferException(e).setUnfinishedMessage(result);
} catch (RuntimeException e) {
if (e.getCause() instanceof InvalidProtocolBufferException) {
throw (InvalidProtocolBufferException) e.getCause();
@ -1565,11 +1570,16 @@ public abstract class GeneratedMessageLite<
if (result.memoizedHashCode != 0) {
throw new RuntimeException();
}
} catch (InvalidProtocolBufferException e) {
if (e.getThrownFromInputStream()) {
e = new InvalidProtocolBufferException(e);
}
throw e.setUnfinishedMessage(result);
} catch (IOException e) {
if (e.getCause() instanceof InvalidProtocolBufferException) {
throw (InvalidProtocolBufferException) e.getCause();
}
throw new InvalidProtocolBufferException(e.getMessage()).setUnfinishedMessage(result);
throw new InvalidProtocolBufferException(e).setUnfinishedMessage(result);
} catch (IndexOutOfBoundsException e) {
throw InvalidProtocolBufferException.truncatedMessage().setUnfinishedMessage(result);
}
@ -1727,8 +1737,13 @@ public abstract class GeneratedMessageLite<
return null;
}
size = CodedInputStream.readRawVarint32(firstByte, input);
} catch (InvalidProtocolBufferException e) {
if (e.getThrownFromInputStream()) {
e = new InvalidProtocolBufferException(e);
}
throw e;
} catch (IOException e) {
throw new InvalidProtocolBufferException(e.getMessage());
throw new InvalidProtocolBufferException(e);
}
InputStream limitedInput = new LimitedInputStream(input, size);
CodedInputStream codedInput = CodedInputStream.newInstance(limitedInput);

@ -41,6 +41,7 @@ import java.io.IOException;
public class InvalidProtocolBufferException extends IOException {
private static final long serialVersionUID = -1616151763072450476L;
private MessageLite unfinishedMessage = null;
private boolean wasThrownFromInputStream;
public InvalidProtocolBufferException(final String description) {
super(description);
@ -72,6 +73,28 @@ public class InvalidProtocolBufferException extends IOException {
return unfinishedMessage;
}
/** Set by CodedInputStream */
void setThrownFromInputStream() {
/* This write can be racy if the same exception is stored and then thrown by multiple custom
* InputStreams on different threads. But since it only ever moves from false->true, there's no
* problem. A thread checking this condition after catching this exception from a delegate
* stream of CodedInputStream is guaranteed to always observe true, because a write on the same
* thread set the value when the exception left the delegate. A thread checking the same
* condition with an exception created by CodedInputStream is guaranteed to always see false,
* because the exception has not been exposed to any code that could publish it to other threads
* and cause a write.
*/
wasThrownFromInputStream = true;
}
/**
* Allows code catching IOException from CodedInputStream to tell whether this instance was thrown
* by a delegate InputStream, rather than directly by a parse failure.
*/
boolean getThrownFromInputStream() {
return wasThrownFromInputStream;
}
/**
* Unwraps the underlying {@link IOException} if this exception was caused by an I/O problem.
* Otherwise, returns {@code this}.

@ -603,7 +603,12 @@ final class RopeByteString extends ByteString {
@Override
public CodedInputStream newCodedInput() {
return CodedInputStream.newInstance(new RopeInputStream());
// Passing along direct references to internal ByteBuffers can support more efficient parsing
// via aliasing in CodedInputStream for users who wish to use it.
//
// Otherwise we force data copies, both in copying as an input stream and in buffering in the
// CodedInputSteam.
return CodedInputStream.newInstance(asReadOnlyByteBufferList(), /* bufferIsImmutable= */ true);
}
@Override

@ -346,7 +346,7 @@ final class UnsafeUtil {
return MEMORY_ACCESSOR.supportsUnsafeByteBufferOperations();
}
private static boolean determineAndroidSupportByAddressSize(Class<?> addressClass) {
static boolean determineAndroidSupportByAddressSize(Class<?> addressClass) {
if (!Android.isOnAndroidDevice()) {
return false;
}

@ -283,7 +283,7 @@ public class AbstractMessageTest extends TestCase {
Message.Builder abstractMessageBuilder =
new AbstractMessageWrapper.Builder(TestRequiredForeign.newBuilder());
// mergeFrom() should not throw initialization error.
abstractMessageBuilder.mergeFrom(bytes).buildPartial();
Message unused1 = abstractMessageBuilder.mergeFrom(bytes).buildPartial();
try {
abstractMessageBuilder.mergeFrom(bytes).build();
fail();
@ -295,7 +295,7 @@ public class AbstractMessageTest extends TestCase {
Message.Builder dynamicMessageBuilder =
DynamicMessage.newBuilder(TestRequiredForeign.getDescriptor());
// mergeFrom() should not throw initialization error.
dynamicMessageBuilder.mergeFrom(bytes).buildPartial();
Message unused2 = dynamicMessageBuilder.mergeFrom(bytes).buildPartial();
try {
dynamicMessageBuilder.mergeFrom(bytes).build();
fail();

@ -1142,6 +1142,39 @@ public class CodedInputStreamTest extends TestCase {
}
}
public void testIterableByteBufferInputStreamReadBytesWithAlias() throws Exception {
ByteArrayOutputStream byteArrayStream = new ByteArrayOutputStream();
CodedOutputStream output = CodedOutputStream.newInstance(byteArrayStream);
// A bytes field large enough that won't fit into the default block buffer.
// 4.5 is to test the case where the total size of input is not aligned with DEFAULT_BLOCK_SIZE.
final int bytesLength = DEFAULT_BLOCK_SIZE * 4 + (DEFAULT_BLOCK_SIZE / 2);
byte[] bytes = new byte[bytesLength];
for (int i = 0; i < bytesLength; i++) {
bytes[i] = (byte) (i % 256);
}
output.writeByteArrayNoTag(bytes);
output.flush();
// Input data is split into multiple ByteBuffers so that a single bytes spans across them.
// CodedInputStream with aliasing will decode it as a consequent rope by wrapping ByteBuffers.
byte[] data = byteArrayStream.toByteArray();
ArrayList<ByteBuffer> input = new ArrayList<>();
for (int i = 0; i < data.length; i += DEFAULT_BLOCK_SIZE) {
int rl = Math.min(DEFAULT_BLOCK_SIZE, data.length - i);
ByteBuffer rb = ByteBuffer.allocateDirect(rl);
rb.put(data, i, rl);
rb.flip();
input.add(rb);
}
final CodedInputStream inputStream = CodedInputStream.newInstance(input, true);
inputStream.enableAliasing(true);
ByteString result = inputStream.readBytes();
for (int i = 0; i < bytesLength; i++) {
assertEquals((byte) (i % 256), result.byteAt(i));
}
}
public void testCompatibleTypes() throws Exception {
long data = 0x100000000L;
Int64Message message = Int64Message.newBuilder().setData(data).build();
@ -1196,7 +1229,7 @@ public class CodedInputStreamTest extends TestCase {
// Expected
}
}
public void testMaliciousInputStream() throws Exception {
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
CodedOutputStream codedOutputStream = CodedOutputStream.newInstance(outputStream);
@ -1210,17 +1243,17 @@ public class CodedInputStreamTest extends TestCase {
return super.read(b, off, len);
}
};
// test ByteString
CodedInputStream codedInputStream = CodedInputStream.newInstance(inputStream, 1);
ByteString byteString = codedInputStream.readBytes();
assertEquals(0x0, byteString.byteAt(0));
maliciousCapture.get(1)[0] = 0x9;
assertEquals(0x0, byteString.byteAt(0));
// test ByteBuffer
inputStream.reset();
maliciousCapture.clear();
codedInputStream = CodedInputStream.newInstance(inputStream, 1);
@ -1228,10 +1261,10 @@ public class CodedInputStreamTest extends TestCase {
assertEquals(0x0, byteBuffer.get(0));
maliciousCapture.get(1)[0] = 0x9;
assertEquals(0x0, byteBuffer.get(0));
// test byte[]
inputStream.reset();
maliciousCapture.clear();
codedInputStream = CodedInputStream.newInstance(inputStream, 1);
@ -1241,7 +1274,7 @@ public class CodedInputStreamTest extends TestCase {
assertEquals(0x9, byteArray[0]); // MODIFICATION! Should we fix?
// test rawBytes
inputStream.reset();
maliciousCapture.clear();
codedInputStream = CodedInputStream.newInstance(inputStream, 1);
@ -1251,4 +1284,33 @@ public class CodedInputStreamTest extends TestCase {
maliciousCapture.get(1)[0] = 0x9;
assertEquals(0x9, byteArray[0]); // MODIFICATION! Should we fix?
}
public void testInvalidInputYieldsInvalidProtocolBufferException_readTag() throws Exception {
byte[] input = new byte[] {0x0a, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, 0x77};
CodedInputStream inputStream = CodedInputStream.newInstance(input);
try {
inputStream.readTag();
int size = inputStream.readRawVarint32();
inputStream.pushLimit(size);
inputStream.readTag();
fail();
} catch (InvalidProtocolBufferException ex) {
// Expected.
}
}
public void testInvalidInputYieldsInvalidProtocolBufferException_readBytes() throws Exception {
byte[] input =
new byte[] {0x0a, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, 0x67, 0x1a, 0x1a};
CodedInputStream inputStream = CodedInputStream.newInstance(input);
try {
inputStream.readTag();
int size = inputStream.readRawVarint32();
inputStream.pushLimit(size);
inputStream.readBytes();
fail();
} catch (InvalidProtocolBufferException ex) {
// Expected.
}
}
}

@ -69,7 +69,7 @@ public class DynamicMessageTest extends TestCase {
Message.Builder builder = DynamicMessage.newBuilder(TestAllTypes.getDescriptor());
Message firstMessage = builder.build();
// double build()
builder.build();
Message unused = builder.build();
// clear() after build()
builder.clear();
// setters after build()

@ -76,6 +76,7 @@ import junit.framework.TestCase;
*
* @author kenton@google.com Kenton Varda
*/
@SuppressWarnings({"ProtoBuilderReturnValueIgnored", "ReturnValueIgnored"})
public class GeneratedMessageTest extends TestCase {
TestUtil.ReflectionTester reflectionTester =
new TestUtil.ReflectionTester(TestAllTypes.getDescriptor(), null);

@ -1163,8 +1163,8 @@ public class MapForProto2Test extends TestCase {
}
public void testReservedWordsFieldNames() {
ReservedAsMapField.newBuilder().build();
ReservedAsMapFieldWithEnumValue.newBuilder().build();
ReservedAsMapField unused1 = ReservedAsMapField.newBuilder().build();
ReservedAsMapFieldWithEnumValue unused2 = ReservedAsMapFieldWithEnumValue.newBuilder().build();
}
public void testGetMap() {

@ -1294,8 +1294,8 @@ public class MapTest extends TestCase {
}
public void testReservedWordsFieldNames() {
ReservedAsMapField.newBuilder().build();
ReservedAsMapFieldWithEnumValue.newBuilder().build();
ReservedAsMapField unused1 = ReservedAsMapField.newBuilder().build();
ReservedAsMapFieldWithEnumValue unused2 = ReservedAsMapFieldWithEnumValue.newBuilder().build();
}
public void testDeterministicSerialziation() throws Exception {

@ -43,8 +43,10 @@ public class TestBadIdentifiers extends TestCase {
public void testCompilation() {
// If this compiles, it means the generation was correct.
TestBadIdentifiersProto.Deprecated.newBuilder();
TestBadIdentifiersProto.Override.newBuilder();
TestBadIdentifiersProto.Deprecated unused1 =
TestBadIdentifiersProto.Deprecated.newBuilder().build();
TestBadIdentifiersProto.Override unused2 =
TestBadIdentifiersProto.Override.getDefaultInstance();
}
public void testGetDescriptor() {

@ -45,8 +45,10 @@ public final class TestBadIdentifiersLite extends TestCase {
public void testCompilation() {
// If this compiles, it means the generation was correct.
TestBadIdentifiersProto.Deprecated.newBuilder();
TestBadIdentifiersProto.Override.newBuilder();
TestBadIdentifiersProto.Deprecated.Builder builder1 =
TestBadIdentifiersProto.Deprecated.newBuilder();
TestBadIdentifiersProto.Override.Builder builder2 =
TestBadIdentifiersProto.Override.newBuilder();
}
public void testConflictingFieldNames() throws Exception {

@ -1,56 +0,0 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// 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.
// Author: Darick Tong (darick@google.com)
syntax = "proto2";
package protobuf_unittest;
message Proto1 {
option experimental_java_message_interface =
"com.google.protobuf.ExtraInterfaces.HasBoolValue";
option experimental_java_message_interface =
"com.google.protobuf.ExtraInterfaces.HasStringValue<Proto1>";
option experimental_java_builder_interface =
"com.google.protobuf.ExtraInterfaces.HasStringValueBuilder"
"<Proto1, Builder>";
optional string string_value = 1;
optional bool bool_value = 2;
optional bytes byte_value = 3;
optional int32 int_value = 4;
}
message Proto2 {
option experimental_java_message_interface =
"com.google.protobuf.ExtraInterfaces.HasBoolValue";
optional bool bool_value = 1;
}

@ -4,6 +4,7 @@
<arg value="--java_out=lite:${generated.testsources.dir}"/>
<arg value="--proto_path=${protobuf.source.dir}"/>
<arg value="--proto_path=${protobuf.basedir}/java/core/${test.proto.dir}"/>
<arg value="${protobuf.source.dir}/google/protobuf/descriptor.proto"/>
<arg value="${protobuf.source.dir}/google/protobuf/unittest.proto"/>
<arg value="${protobuf.source.dir}/google/protobuf/unittest_import.proto"/>
<arg value="${protobuf.source.dir}/google/protobuf/unittest_import_lite.proto"/>

@ -173,6 +173,7 @@
<include>UnknownFieldSetLite.java</include>
<include>UnknownFieldSetLiteSchema.java</include>
<include>UnmodifiableLazyStringList.java</include>
<include>UnsafeByteOperations.java</include>
<include>UnsafeUtil.java</include>
<include>Utf8.java</include>
<include>WireFormat.java</include>

@ -38,6 +38,7 @@ import com.google.protobuf.UnittestImportLite.ImportEnumLite;
import com.google.protobuf.UnittestImportPublicLite.PublicImportMessageLite;
import com.google.protobuf.UnittestLite.ForeignEnumLite;
import com.google.protobuf.UnittestLite.ForeignMessageLite;
import com.google.protobuf.UnittestLite.RecursiveMessage;
import com.google.protobuf.UnittestLite.TestAllExtensionsLite;
import com.google.protobuf.UnittestLite.TestAllTypesLite;
import com.google.protobuf.UnittestLite.TestAllTypesLite.NestedEnum;
@ -61,6 +62,7 @@ import protobuf_unittest.lite_equals_and_hash.LiteEqualsAndHash.TestRecursiveOne
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.Field;
import java.nio.ByteBuffer;
@ -1638,6 +1640,160 @@ public class LiteTest extends TestCase {
}
}
public void testParseFromStream_IOExceptionNotLost() throws Exception {
final IOException readException = new IOException();
try {
TestAllTypesLite.parseFrom(
CodedInputStream.newInstance(
new InputStream() {
@Override
public int read() throws IOException {
throw readException;
}
}));
fail();
} catch (InvalidProtocolBufferException expected) {
boolean found = false;
for (Throwable exception = expected; exception != null; exception = exception.getCause()) {
if (exception == readException) {
found = true;
break;
}
}
if (!found) {
throw new AssertionError("Lost cause of parsing error", expected);
}
}
}
public void testParseDelimitedFromStream_IOExceptionNotLost() throws Exception {
final IOException readException = new IOException();
try {
TestAllTypesLite.parseDelimitedFrom(
new InputStream() {
@Override
public int read() throws IOException {
throw readException;
}
});
fail();
} catch (InvalidProtocolBufferException expected) {
boolean found = false;
for (Throwable exception = expected; exception != null; exception = exception.getCause()) {
if (exception == readException) {
found = true;
break;
}
}
if (!found) {
throw new AssertionError("Lost cause of parsing error", expected);
}
}
}
public void testParseFromArray_manyNestedMessagesError() throws Exception {
RecursiveMessage.Builder recursiveMessage =
RecursiveMessage.newBuilder().setPayload(ByteString.copyFrom(new byte[1]));
for (int i = 0; i < 20; i++) {
recursiveMessage = RecursiveMessage.newBuilder().setRecurse(recursiveMessage.build());
}
byte[] result = recursiveMessage.build().toByteArray();
result[
result.length
- CodedOutputStream.computeTagSize(RecursiveMessage.PAYLOAD_FIELD_NUMBER)
- CodedOutputStream.computeLengthDelimitedFieldSize(1)] =
0; // Set invalid tag
try {
RecursiveMessage.parseFrom(result);
fail("Result was: " + Arrays.toString(result));
} catch (InvalidProtocolBufferException expected) {
boolean found = false;
int exceptionCount = 0;
for (Throwable exception = expected; exception != null; exception = exception.getCause()) {
if (exception instanceof InvalidProtocolBufferException) {
exceptionCount++;
}
for (StackTraceElement element : exception.getStackTrace()) {
if (InvalidProtocolBufferException.class.getName().equals(element.getClassName())
&& "invalidTag".equals(element.getMethodName())) {
found = true;
} else if (Android.isOnAndroidDevice()
&& "decodeUnknownField".equals(element.getMethodName())) {
// Android is missing the first element of the stack trace - b/181147885
found = true;
}
}
}
if (!found) {
throw new AssertionError("Lost cause of parsing error", expected);
}
if (exceptionCount > 1) {
throw new AssertionError(exceptionCount + " nested parsing exceptions", expected);
}
}
}
public void testParseFromStream_manyNestedMessagesError() throws Exception {
RecursiveMessage.Builder recursiveMessage =
RecursiveMessage.newBuilder().setPayload(ByteString.copyFrom(new byte[1]));
for (int i = 0; i < 20; i++) {
recursiveMessage = RecursiveMessage.newBuilder().setRecurse(recursiveMessage.build());
}
byte[] result = recursiveMessage.build().toByteArray();
result[
result.length
- CodedOutputStream.computeTagSize(RecursiveMessage.PAYLOAD_FIELD_NUMBER)
- CodedOutputStream.computeLengthDelimitedFieldSize(1)] =
0; // Set invalid tag
try {
RecursiveMessage.parseFrom(CodedInputStream.newInstance(new ByteArrayInputStream(result)));
fail("Result was: " + Arrays.toString(result));
} catch (InvalidProtocolBufferException expected) {
boolean found = false;
int exceptionCount = 0;
for (Throwable exception = expected; exception != null; exception = exception.getCause()) {
if (exception instanceof InvalidProtocolBufferException) {
exceptionCount++;
}
for (StackTraceElement element : exception.getStackTrace()) {
if (InvalidProtocolBufferException.class.getName().equals(element.getClassName())
&& "invalidTag".equals(element.getMethodName())) {
found = true;
} else if (Android.isOnAndroidDevice() && "readTag".equals(element.getMethodName())) {
// Android is missing the first element of the stack trace - b/181147885
found = true;
}
}
}
if (!found) {
throw new AssertionError("Lost cause of parsing error", expected);
}
if (exceptionCount > 1) {
throw new AssertionError(exceptionCount + " nested parsing exceptions", expected);
}
}
}
public void testParseFromStream_sneakyNestedException() throws Exception {
final InvalidProtocolBufferException sketchy =
new InvalidProtocolBufferException("Created in a sketchy way!")
.setUnfinishedMessage(TestAllTypesLite.getDefaultInstance());
try {
RecursiveMessage.parseFrom(
CodedInputStream.newInstance(
new InputStream() {
@Override
public int read() throws IOException {
throw sketchy;
}
}));
fail();
} catch (InvalidProtocolBufferException expected) {
assertNotSame(expected, sketchy);
}
assertEquals(sketchy.getUnfinishedMessage(), TestAllTypesLite.getDefaultInstance());
}
public void testMergeFrom_sanity() throws Exception {
TestAllTypesLite one = TestUtilLite.getAllLiteSetBuilder().build();
byte[] bytes = one.toByteArray();
@ -2250,24 +2406,26 @@ public class LiteTest extends TestCase {
}
public void testAddAllIteratesOnce() {
TestAllTypesLite.newBuilder()
.addAllRepeatedBool(new OneTimeIterableList<>(false))
.addAllRepeatedInt32(new OneTimeIterableList<>(0))
.addAllRepeatedInt64(new OneTimeIterableList<>(0L))
.addAllRepeatedFloat(new OneTimeIterableList<>(0f))
.addAllRepeatedDouble(new OneTimeIterableList<>(0d))
.addAllRepeatedBytes(new OneTimeIterableList<>(ByteString.EMPTY))
.addAllRepeatedString(new OneTimeIterableList<>(""))
.addAllRepeatedNestedMessage(new OneTimeIterableList<>(NestedMessage.getDefaultInstance()))
.addAllRepeatedBool(new OneTimeIterable<>(false))
.addAllRepeatedInt32(new OneTimeIterable<>(0))
.addAllRepeatedInt64(new OneTimeIterable<>(0L))
.addAllRepeatedFloat(new OneTimeIterable<>(0f))
.addAllRepeatedDouble(new OneTimeIterable<>(0d))
.addAllRepeatedBytes(new OneTimeIterable<>(ByteString.EMPTY))
.addAllRepeatedString(new OneTimeIterable<>(""))
.addAllRepeatedNestedMessage(new OneTimeIterable<>(NestedMessage.getDefaultInstance()))
.build();
TestAllTypesLite unused =
TestAllTypesLite.newBuilder()
.addAllRepeatedBool(new OneTimeIterableList<>(false))
.addAllRepeatedInt32(new OneTimeIterableList<>(0))
.addAllRepeatedInt64(new OneTimeIterableList<>(0L))
.addAllRepeatedFloat(new OneTimeIterableList<>(0f))
.addAllRepeatedDouble(new OneTimeIterableList<>(0d))
.addAllRepeatedBytes(new OneTimeIterableList<>(ByteString.EMPTY))
.addAllRepeatedString(new OneTimeIterableList<>(""))
.addAllRepeatedNestedMessage(
new OneTimeIterableList<>(NestedMessage.getDefaultInstance()))
.addAllRepeatedBool(new OneTimeIterable<>(false))
.addAllRepeatedInt32(new OneTimeIterable<>(0))
.addAllRepeatedInt64(new OneTimeIterable<>(0L))
.addAllRepeatedFloat(new OneTimeIterable<>(0f))
.addAllRepeatedDouble(new OneTimeIterable<>(0d))
.addAllRepeatedBytes(new OneTimeIterable<>(ByteString.EMPTY))
.addAllRepeatedString(new OneTimeIterable<>(""))
.addAllRepeatedNestedMessage(new OneTimeIterable<>(NestedMessage.getDefaultInstance()))
.build();
}
public void testAddAllIteratesOnce_throwsOnNull() {

@ -75,7 +75,7 @@
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.1</version>
<version>4.13.2</version>
<scope>test</scope>
</dependency>
<dependency>
@ -93,18 +93,18 @@
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>30.0-android</version>
<version>30.1-android</version>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava-testlib</artifactId>
<version>30.0-android</version>
<version>30.1-android</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.google.truth</groupId>
<artifactId>truth</artifactId>
<version>1.0.1</version>
<version>1.1.2</version>
<scope>test</scope>
</dependency>
</dependencies>

@ -149,6 +149,12 @@ public final class Durations {
return (duration.getSeconds() == 0) ? duration.getNanos() < 0 : duration.getSeconds() < 0;
}
/** Returns whether the given {@link Duration} is positive or not. */
public static boolean isPositive(Duration duration) {
checkValid(duration);
return !isNegative(duration) && !duration.equals(ZERO);
}
/**
* Ensures that the given {@link Duration} is not negative.
*
@ -157,7 +163,6 @@ public final class Durations {
*/
@CanIgnoreReturnValue
public static Duration checkNotNegative(Duration duration) {
checkValid(duration);
checkArgument(!isNegative(duration), "duration (%s) must not be negative", toString(duration));
return duration;
}
@ -170,11 +175,7 @@ public final class Durations {
*/
@CanIgnoreReturnValue
public static Duration checkPositive(Duration duration) {
checkValid(duration);
checkArgument(
!isNegative(duration) && !duration.equals(ZERO),
"duration (%s) must be positive",
toString(duration));
checkArgument(isPositive(duration), "duration (%s) must be positive", toString(duration));
return duration;
}

@ -1,4 +1,4 @@
FROM debian:stretch
FROM debian:buster
# Install dependencies. We start with the basic ones require to build protoc
# and the C++ build
@ -22,14 +22,18 @@ RUN apt-get update && apt-get install -y \
wget \
&& apt-get clean
# Update ca-certificates to fix known buster + .NET 5 issue
# https://github.com/NuGet/Announcements/issues/49
RUN apt-get update && apt-get install -y ca-certificates && apt-get clean
# dotnet SDK prerequisites
RUN apt-get update && apt-get install -y libunwind8 libicu57 && apt-get clean
RUN apt-get update && apt-get install -y libunwind8 libicu63 && apt-get clean
# Install dotnet SDK via install script
RUN wget -q https://dot.net/v1/dotnet-install.sh && \
chmod u+x dotnet-install.sh && \
./dotnet-install.sh --version 2.1.802 && \
./dotnet-install.sh --version 3.1.301 && \
./dotnet-install.sh --version 5.0.102 && \
ln -s /root/.dotnet/dotnet /usr/local/bin
RUN wget -q www.nuget.org/NuGet.exe -O /usr/local/bin/nuget.exe

@ -1,17 +0,0 @@
#!/bin/bash
#
# This is the top-level script we give to Kokoro as the entry point for
# running the "pull request" project:
#
# This script selects a specific Dockerfile (for building a Docker image) and
# a script to run inside that image. Then we delegate to the general
# build_and_run_docker.sh script.
# Change to repo root
cd $(dirname $0)/../../..
export DOCKERFILE_DIR=kokoro/linux/64-bit
export DOCKER_RUN_SCRIPT=kokoro/linux/pull_request_in_docker.sh
export OUTPUT_DIR=testoutput
export TEST_SET="python"
./kokoro/linux/build_and_run_docker.sh

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

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

@ -23,7 +23,7 @@ sudo apt install -y g++-powerpc64le-linux-gnu
protoc-artifacts/build-protoc.sh linux ppcle_64 protoc
sudo apt install -y g++-s390x-linux-gnu
protoc-artifacts/build-protoc.sh linux s390x protoc
protoc-artifacts/build-protoc.sh linux s390_64 protoc
# Use docker image to build linux artifacts.
DOCKER_IMAGE_NAME=protobuf/protoc_$(sha1sum protoc-artifacts/Dockerfile | cut -f1 -d " ")

@ -49,9 +49,31 @@ build_artifact_version() {
sudo rm -rf $REPO_DIR
}
build_crosscompiled_aarch64_artifact_version() {
# crosscompilation is only supported with the dockcross manylinux2014 image
DOCKER_IMAGE=dockcross/manylinux2014-aarch64
PLAT=aarch64
# TODO(jtatermusch): currently when crosscompiling, "auditwheel repair" will be disabled
# since auditwheel doesn't work for crosscomiled wheels.
build_artifact_version $@
}
build_artifact_version 2.7
build_artifact_version 3.5
build_artifact_version 3.6
build_artifact_version 3.7
build_artifact_version 3.8
build_artifact_version 3.9
build_crosscompiled_aarch64_artifact_version 3.7
build_crosscompiled_aarch64_artifact_version 3.8
build_crosscompiled_aarch64_artifact_version 3.9
# Put the aarch64 manylinux wheels under the "unofficial" subdirectory.
# Only wheels directly under the artifacts/ directory will be published
# to PyPI as part of the protobuf release process.
# TODO(jtattermusch): include aarch64 wheels in the release
# once they are sufficiently tested.
mkdir -p $ARTIFACT_DIR/unofficial
mv $ARTIFACT_DIR/protobuf-*-manylinux*_aarch64.whl $ARTIFACT_DIR/unofficial

@ -6,15 +6,38 @@ function pre_build {
# Runs in the root directory of this repository.
pushd protobuf
yum install -y devtoolset-2-libatomic-devel
if [ "$PLAT" == "aarch64" ]
then
local configure_host_flag="--host=aarch64"
else
yum install -y devtoolset-2-libatomic-devel
fi
# Build protoc
# Build protoc and libprotobuf
./autogen.sh
./configure
CXXFLAGS="-fPIC -g -O2" ./configure
CXXFLAGS="-fPIC -g -O2" ./configure $configure_host_flag
make -j8
if [ "$PLAT" == "aarch64" ]
then
# we are crosscompiling for aarch64 while running on x64
# the simplest way for build_py command to be able to generate
# the protos is by running the protoc process under
# an emulator. That way we don't have to build a x64 version
# of protoc. The qemu-arm emulator is already included
# in the dockcross docker image.
# Running protoc under an emulator is fast as protoc doesn't
# really do much.
# create a simple shell wrapper that runs crosscompiled protoc under qemu
echo '#!/bin/bash' >protoc_qemu_wrapper.sh
echo 'exec qemu-aarch64 "../src/protoc" "$@"' >>protoc_qemu_wrapper.sh
chmod ugo+x protoc_qemu_wrapper.sh
# PROTOC variable is by build_py step that runs under ./python directory
export PROTOC=../protoc_qemu_wrapper.sh
fi
# Generate python dependencies.
pushd python
python setup.py build_py
@ -35,7 +58,20 @@ function bdist_wheel_cmd {
# Modify build version
pwd
ls
python setup.py bdist_wheel --cpp_implementation --compile_static_extension
if [ "$PLAT" == "aarch64" ]
then
# when crosscompiling for aarch64, --plat-name needs to be set explicitly
# to end up with correctly named wheel file
# the value should be manylinuxABC_ARCH and dockcross docker image
# conveniently provides the value in the AUDITWHEEL_PLAT env
local plat_name_flag="--plat-name=$AUDITWHEEL_PLAT"
# override the value of EXT_SUFFIX to make sure the crosscompiled .so files in the wheel have the correct filename suffix
export PROTOCOL_BUFFERS_OVERRIDE_EXT_SUFFIX="$(python -c 'import sysconfig; print(sysconfig.get_config_var("EXT_SUFFIX").replace("-x86_64-linux-gnu.so", "-aarch64-linux-gnu.so"))')"
fi
python setup.py bdist_wheel --cpp_implementation --compile_static_extension $plat_name_flag
cp dist/*.whl $abs_wheelhouse
}
@ -48,3 +84,12 @@ function run_tests {
python --version
python -c "from google.protobuf.pyext import _message;"
}
if [ "$PLAT" == "aarch64" ]
then
# when crosscompiling for aarch64, override the default multibuild's repair_wheelhouse logic
# since "auditwheel repair" doesn't work for crosscompiled wheels
function repair_wheelhouse {
echo "Skipping repair_wheelhouse since auditwheel requires build architecture to match wheel architecture."
}
fi

@ -34,18 +34,20 @@
#import "GPBDescriptor.h"
@implementation GPBExtensionRegistry {
NSMutableDictionary *mutableClassMap_;
CFMutableDictionaryRef mutableClassMap_;
}
- (instancetype)init {
if ((self = [super init])) {
mutableClassMap_ = [[NSMutableDictionary alloc] init];
// The keys are ObjC classes, so straight up ptr comparisons are fine.
mutableClassMap_ = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, NULL,
&kCFTypeDictionaryValueCallBacks);
}
return self;
}
- (void)dealloc {
[mutableClassMap_ release];
CFRelease(mutableClassMap_);
[super dealloc];
}
@ -68,14 +70,13 @@
Class containingMessageClass = extension.containingMessageClass;
CFMutableDictionaryRef extensionMap = (CFMutableDictionaryRef)
[mutableClassMap_ objectForKey:containingMessageClass];
CFDictionaryGetValue(mutableClassMap_, containingMessageClass);
if (extensionMap == nil) {
// Use a custom dictionary here because the keys are numbers and conversion
// back and forth from NSNumber isn't worth the cost.
extensionMap = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, NULL,
&kCFTypeDictionaryValueCallBacks);
[mutableClassMap_ setObject:(id)extensionMap
forKey:(id<NSCopying>)containingMessageClass];
CFDictionarySetValue(mutableClassMap_, containingMessageClass, extensionMap);
CFRelease(extensionMap);
}
@ -87,7 +88,7 @@
fieldNumber:(NSInteger)fieldNumber {
Class messageClass = descriptor.messageClass;
CFMutableDictionaryRef extensionMap = (CFMutableDictionaryRef)
[mutableClassMap_ objectForKey:messageClass];
CFDictionaryGetValue(mutableClassMap_, messageClass);
ssize_t key = fieldNumber;
GPBExtensionDescriptor *result =
(extensionMap
@ -101,28 +102,28 @@ static void CopyKeyValue(const void *key, const void *value, void *context) {
CFDictionarySetValue(extensionMap, key, value);
}
static void CopySubDictionary(const void *key, const void *value, void *context) {
CFMutableDictionaryRef mutableClassMap = (CFMutableDictionaryRef)context;
Class containingMessageClass = key;
CFMutableDictionaryRef otherExtensionMap = (CFMutableDictionaryRef)value;
CFMutableDictionaryRef extensionMap = (CFMutableDictionaryRef)
CFDictionaryGetValue(mutableClassMap, containingMessageClass);
if (extensionMap == nil) {
extensionMap = CFDictionaryCreateMutableCopy(kCFAllocatorDefault, 0, otherExtensionMap);
CFDictionarySetValue(mutableClassMap, containingMessageClass, extensionMap);
CFRelease(extensionMap);
} else {
CFDictionaryApplyFunction(otherExtensionMap, CopyKeyValue, extensionMap);
}
}
- (void)addExtensions:(GPBExtensionRegistry *)registry {
if (registry == nil) {
// In the case where there are no extensions just ignore.
return;
}
NSMutableDictionary *otherClassMap = registry->mutableClassMap_;
[otherClassMap enumerateKeysAndObjectsUsingBlock:^(id key, id value, BOOL * stop) {
#pragma unused(stop)
Class containingMessageClass = key;
CFMutableDictionaryRef otherExtensionMap = (CFMutableDictionaryRef)value;
CFMutableDictionaryRef extensionMap = (CFMutableDictionaryRef)
[mutableClassMap_ objectForKey:containingMessageClass];
if (extensionMap == nil) {
extensionMap = CFDictionaryCreateMutableCopy(kCFAllocatorDefault, 0, otherExtensionMap);
[mutableClassMap_ setObject:(id)extensionMap
forKey:(id<NSCopying>)containingMessageClass];
CFRelease(extensionMap);
} else {
CFDictionaryApplyFunction(otherExtensionMap, CopyKeyValue, extensionMap);
}
}];
CFDictionaryApplyFunction(registry->mutableClassMap_, CopySubDictionary, mutableClassMap_);
}
#pragma clang diagnostic pop

@ -16,8 +16,8 @@ generation functionality.
To use PHP runtime library requires:
- C extension: PHP 5.5, 5.6, or 7.
- [PHP package](http://php.net/downloads.php): PHP 5.5, 5.6 or 7.
- C extension: PHP 7.x, 8.0
- [PHP package](http://php.net/downloads.php): PHP 5.5, 5.6, 7.x, or 8.0.
## Installation

@ -25,20 +25,20 @@ class FileOptions extends \Google\Protobuf\Internal\Message
*/
protected $java_package = null;
/**
* If set, all the classes from the .proto file are wrapped in a single
* outer class with the given name. This applies to both Proto1
* (equivalent to the old "--one_java_file" option) and Proto2 (where
* a .proto always translates to a single class, but you may want to
* explicitly choose the class name).
* Controls the name of the wrapper Java class generated for the .proto file.
* That class will always contain the .proto file's getDescriptor() method as
* well as any top-level extensions defined in the .proto file.
* If java_multiple_files is disabled, then all the other classes from the
* .proto file will be nested inside the single wrapper outer class.
*
* Generated from protobuf field <code>optional string java_outer_classname = 8;</code>
*/
protected $java_outer_classname = null;
/**
* If set true, then the Java code generator will generate a separate .java
* If enabled, then the Java code generator will generate a separate .java
* file for each top-level message, enum, and service defined in the .proto
* file. Thus, these types will *not* be nested inside the outer class
* named by java_outer_classname. However, the outer class will still be
* file. Thus, these types will *not* be nested inside the wrapper class
* named by java_outer_classname. However, the wrapper class will still be
* generated to contain the file's getDescriptor() method as well as any
* top-level extensions defined in the file.
*
@ -192,16 +192,16 @@ class FileOptions extends \Google\Protobuf\Internal\Message
* inappropriate because proto packages do not normally start with backwards
* domain names.
* @type string $java_outer_classname
* If set, all the classes from the .proto file are wrapped in a single
* outer class with the given name. This applies to both Proto1
* (equivalent to the old "--one_java_file" option) and Proto2 (where
* a .proto always translates to a single class, but you may want to
* explicitly choose the class name).
* Controls the name of the wrapper Java class generated for the .proto file.
* That class will always contain the .proto file's getDescriptor() method as
* well as any top-level extensions defined in the .proto file.
* If java_multiple_files is disabled, then all the other classes from the
* .proto file will be nested inside the single wrapper outer class.
* @type bool $java_multiple_files
* If set true, then the Java code generator will generate a separate .java
* If enabled, then the Java code generator will generate a separate .java
* file for each top-level message, enum, and service defined in the .proto
* file. Thus, these types will *not* be nested inside the outer class
* named by java_outer_classname. However, the outer class will still be
* file. Thus, these types will *not* be nested inside the wrapper class
* named by java_outer_classname. However, the wrapper class will still be
* generated to contain the file's getDescriptor() method as well as any
* top-level extensions defined in the file.
* @type bool $java_generate_equals_and_hash
@ -319,11 +319,11 @@ class FileOptions extends \Google\Protobuf\Internal\Message
}
/**
* If set, all the classes from the .proto file are wrapped in a single
* outer class with the given name. This applies to both Proto1
* (equivalent to the old "--one_java_file" option) and Proto2 (where
* a .proto always translates to a single class, but you may want to
* explicitly choose the class name).
* Controls the name of the wrapper Java class generated for the .proto file.
* That class will always contain the .proto file's getDescriptor() method as
* well as any top-level extensions defined in the .proto file.
* If java_multiple_files is disabled, then all the other classes from the
* .proto file will be nested inside the single wrapper outer class.
*
* Generated from protobuf field <code>optional string java_outer_classname = 8;</code>
* @return string
@ -344,11 +344,11 @@ class FileOptions extends \Google\Protobuf\Internal\Message
}
/**
* If set, all the classes from the .proto file are wrapped in a single
* outer class with the given name. This applies to both Proto1
* (equivalent to the old "--one_java_file" option) and Proto2 (where
* a .proto always translates to a single class, but you may want to
* explicitly choose the class name).
* Controls the name of the wrapper Java class generated for the .proto file.
* That class will always contain the .proto file's getDescriptor() method as
* well as any top-level extensions defined in the .proto file.
* If java_multiple_files is disabled, then all the other classes from the
* .proto file will be nested inside the single wrapper outer class.
*
* Generated from protobuf field <code>optional string java_outer_classname = 8;</code>
* @param string $var
@ -363,10 +363,10 @@ class FileOptions extends \Google\Protobuf\Internal\Message
}
/**
* If set true, then the Java code generator will generate a separate .java
* If enabled, then the Java code generator will generate a separate .java
* file for each top-level message, enum, and service defined in the .proto
* file. Thus, these types will *not* be nested inside the outer class
* named by java_outer_classname. However, the outer class will still be
* file. Thus, these types will *not* be nested inside the wrapper class
* named by java_outer_classname. However, the wrapper class will still be
* generated to contain the file's getDescriptor() method as well as any
* top-level extensions defined in the file.
*
@ -389,10 +389,10 @@ class FileOptions extends \Google\Protobuf\Internal\Message
}
/**
* If set true, then the Java code generator will generate a separate .java
* If enabled, then the Java code generator will generate a separate .java
* file for each top-level message, enum, and service defined in the .proto
* file. Thus, these types will *not* be nested inside the outer class
* named by java_outer_classname. However, the outer class will still be
* file. Thus, these types will *not* be nested inside the wrapper class
* named by java_outer_classname. However, the wrapper class will still be
* generated to contain the file's getDescriptor() method as well as any
* top-level extensions defined in the file.
*

@ -67,7 +67,7 @@ class RepeatedField implements \ArrayAccess, \IteratorAggregate, \Countable
/**
* Constructs an instance of RepeatedField.
*
* @param long $type Type of the stored element.
* @param integer $type Type of the stored element.
* @param string $klass Message/Enum class name (message/enum fields only).
* @ignore
*/
@ -116,7 +116,7 @@ class RepeatedField implements \ArrayAccess, \IteratorAggregate, \Countable
*
* This will also be called for: $ele = $arr[0]
*
* @param long $offset The index of the element to be fetched.
* @param integer $offset The index of the element to be fetched.
* @return object The stored element at given index.
* @throws \ErrorException Invalid type for index.
* @throws \ErrorException Non-existing index.
@ -131,7 +131,7 @@ class RepeatedField implements \ArrayAccess, \IteratorAggregate, \Countable
*
* This will also be called for: $arr []= $ele and $arr[0] = ele
*
* @param long $offset The index of the element to be assigned.
* @param integer $offset The index of the element to be assigned.
* @param object $value The element to be assigned.
* @return void
* @throws \ErrorException Invalid type for index.
@ -204,7 +204,7 @@ class RepeatedField implements \ArrayAccess, \IteratorAggregate, \Countable
*
* This will also be called for: unset($arr)
*
* @param long $offset The index of the element to be removed.
* @param integer $offset The index of the element to be removed.
* @return void
* @throws \ErrorException Invalid type for index.
* @throws \ErrorException The element to be removed is not at the end of the
@ -227,7 +227,7 @@ class RepeatedField implements \ArrayAccess, \IteratorAggregate, \Countable
*
* This will also be called for: isset($arr)
*
* @param long $offset The index of the element to be removed.
* @param integer $offset The index of the element to be removed.
* @return bool True if the element at the given offset exists.
* @throws \ErrorException Invalid type for index.
*/

@ -20,7 +20,7 @@ the following files:
## Maven Location
The published protoc artifacts are available on Maven here:
http://central.maven.org/maven2/com/google/protobuf/protoc/
https://repo.maven.apache.org/maven2/com/google/protobuf/protoc/
## Versioning
The version of the ``protoc`` artifact must be the same as the version of the
@ -123,7 +123,7 @@ target directory layout:
protoc.exe
+ ppcle_64
protoc.exe
+ s390x
+ s390_64
protoc.exe
+ osx
+ x86_64

@ -93,7 +93,7 @@ checkArch ()
assertEq $format "elf64-x86-64" $LINENO
elif [[ "$ARCH" == aarch_64 ]]; then
assertEq $format "elf64-little" $LINENO
elif [[ "$ARCH" == s390x ]]; then
elif [[ "$ARCH" == s390_64 ]]; then
if [[ $host_machine == s390x ]];then
assertEq $format "elf64-s390" $LINENO
else
@ -149,7 +149,7 @@ checkDependencies ()
white_list="linux-gate\.so\.1\|libpthread\.so\.0\|libm\.so\.6\|libc\.so\.6\|ld-linux\.so\.2"
elif [[ "$ARCH" == x86_64 ]]; then
white_list="linux-vdso\.so\.1\|libpthread\.so\.0\|libm\.so\.6\|libc\.so\.6\|ld-linux-x86-64\.so\.2"
elif [[ "$ARCH" == s390x ]]; then
elif [[ "$ARCH" == s390_64 ]]; then
if [[ $host_machine != s390x ]];then
dump_cmd='objdump -p '"$1"' | grep NEEDED'
fi
@ -226,7 +226,7 @@ elif [[ "$(uname)" == Linux* ]]; then
elif [[ "$ARCH" == ppcle_64 ]]; then
CXXFLAGS="$CXXFLAGS -m64"
CONFIGURE_ARGS="$CONFIGURE_ARGS --host=powerpc64le-linux-gnu"
elif [[ "$ARCH" == s390x ]]; then
elif [[ "$ARCH" == s390_64 ]]; then
CXXFLAGS="$CXXFLAGS -m64"
CONFIGURE_ARGS="$CONFIGURE_ARGS --host=s390x-linux-gnu"
else

@ -21,7 +21,7 @@ included. Each invocation will create 8 zip packages:
dist/<TARGET>-<VERSION_NUMBER>-linux-x86_64.zip
dist/<TARGET>-<VERSION_NUMBER>-linux-aarch_64.zip
dist/<TARGET>-<VERSION_NUMBER>-linux-ppcle_64.zip
dist/<TARGET>-<VERSION_NUMBER>-linux-s390x.zip
dist/<TARGET>-<VERSION_NUMBER>-linux-s390_64.zip
EOF
exit 1
fi
@ -38,7 +38,7 @@ declare -a FILE_NAMES=( \
linux-x86_64.zip linux-x86_64.exe \
linux-aarch_64.zip linux-aarch_64.exe \
linux-ppcle_64.zip linux-ppcle_64.exe \
linux-s390x.zip linux-s390x.exe \
linux-s390_64.zip linux-s390_64.exe \
)
# List of all well-known types to be included.

@ -81,8 +81,8 @@
<type>exe</type>
</artifact>
<artifact>
<file>${basedir}/target/linux/s390x/protoc.exe</file>
<classifier>linux-s390x</classifier>
<file>${basedir}/target/linux/s390_64/protoc.exe</file>
<classifier>linux-s390_64</classifier>
<type>exe</type>
</artifact>
</artifacts>

@ -841,8 +841,7 @@ class MessageTest(unittest.TestCase):
m1.MergeFromString(m2.SerializeToString())
self.assertEqual(1, m1.optional_nested_message.bb)
@unittest.skipIf(six.PY2, 'memoryview objects are not supported on py2')
def testMergeFromStringUsingMemoryViewWorksInPy3(self, message_module):
def testMergeFromStringUsingMemoryView(self, message_module):
m2 = message_module.TestAllTypes()
m2.optional_string = 'scalar string'
m2.repeated_string.append('repeated string')
@ -864,12 +863,6 @@ class MessageTest(unittest.TestCase):
self.assertIsInstance(m1.optional_string, six.text_type)
self.assertIsInstance(m1.repeated_string[0], six.text_type)
@unittest.skipIf(six.PY3, 'memoryview is supported by py3')
def testMergeFromStringUsingMemoryViewIsPy2Error(self, message_module):
memview = memoryview(b'')
with self.assertRaises(TypeError):
message_module.TestAllTypes.FromString(memview)
def testMergeFromEmpty(self, message_module):
m1 = message_module.TestAllTypes()
# Cpp extension will lazily create a sub message which is immutable.

@ -1133,12 +1133,6 @@ def _AddSerializePartialToStringMethod(message_descriptor, cls):
def _AddMergeFromStringMethod(message_descriptor, cls):
"""Helper for _AddMessageMethods()."""
def MergeFromString(self, serialized):
if isinstance(serialized, memoryview) and six.PY2:
raise TypeError(
'memoryview not supported in Python 2 with the pure Python proto '
'implementation: this is to maintain compatibility with the C++ '
'implementation')
serialized = memoryview(serialized)
length = len(serialized)
try:

@ -1176,6 +1176,54 @@ class OnlyWorksWithProto2RightNowTests(TextFormatBase):
' }\n'
'}\n')
def testDuplicateMapKey(self):
message = map_unittest_pb2.TestMap()
text = (
'map_uint64_uint64 {\n'
' key: 123\n'
' value: 17179869184\n'
'}\n'
'map_string_string {\n'
' key: "abc"\n'
' value: "first"\n'
'}\n'
'map_int32_foreign_message {\n'
' key: 111\n'
' value {\n'
' c: 5\n'
' }\n'
'}\n'
'map_uint64_uint64 {\n'
' key: 123\n'
' value: 321\n'
'}\n'
'map_string_string {\n'
' key: "abc"\n'
' value: "second"\n'
'}\n'
'map_int32_foreign_message {\n'
' key: 111\n'
' value {\n'
' d: 5\n'
' }\n'
'}\n')
text_format.Parse(text, message)
self.CompareToGoldenText(
text_format.MessageToString(message), 'map_uint64_uint64 {\n'
' key: 123\n'
' value: 321\n'
'}\n'
'map_string_string {\n'
' key: "abc"\n'
' value: "second"\n'
'}\n'
'map_int32_foreign_message {\n'
' key: 111\n'
' value {\n'
' d: 5\n'
' }\n'
'}\n')
# In cpp implementation, __str__ calls the cpp implementation of text format.
def testPrintMapUsingCppImplementation(self):
message = map_unittest_pb2.TestMap()
@ -2348,6 +2396,13 @@ class OptionalColonMessageToStringTest(unittest.TestCase):
'}\n')
self.assertEqual(expected, output)
def testPrintShortFormatRepeatedFields(self):
message = unittest_pb2.TestAllTypes()
message.repeated_int32.append(1)
output = text_format.MessageToString(
message, use_short_repeated_primitives=True, force_colon=True)
self.assertEqual('repeated_int32: [1]\n', output)
if __name__ == '__main__':
unittest.main()

@ -30,15 +30,18 @@
// Author: petar@google.com (Petar Petrov)
#include <google/protobuf/pyext/descriptor.h>
#include <Python.h>
#include <frameobject.h>
#include <cstdint>
#include <string>
#include <unordered_map>
#include <google/protobuf/io/coded_stream.h>
#include <google/protobuf/descriptor.pb.h>
#include <google/protobuf/dynamic_message.h>
#include <google/protobuf/pyext/descriptor.h>
#include <google/protobuf/pyext/descriptor_containers.h>
#include <google/protobuf/pyext/descriptor_pool.h>
#include <google/protobuf/pyext/message.h>
@ -195,7 +198,7 @@ bool Reparse(
std::string serialized;
from.SerializeToString(&serialized);
io::CodedInputStream input(
reinterpret_cast<const uint8*>(serialized.c_str()), serialized.size());
reinterpret_cast<const uint8_t*>(serialized.c_str()), serialized.size());
input.SetExtensionRegistry(message_factory->pool->pool,
message_factory->message_factory);
bool success = to->ParseFromCodedStream(&input);
@ -247,8 +250,9 @@ static PyObject* GetOrBuildOptions(const DescriptorClass *descriptor) {
message_type->full_name().c_str());
return NULL;
}
ScopedPyObjectPtr args(PyTuple_New(0));
ScopedPyObjectPtr value(
PyEval_CallObject(message_class->AsPyObject(), NULL));
PyObject_Call(message_class->AsPyObject(), args.get(), NULL));
Py_DECREF(message_class);
if (value == NULL) {
return NULL;
@ -804,22 +808,22 @@ static PyObject* GetDefaultValue(PyBaseDescriptor *self, void *closure) {
switch (_GetDescriptor(self)->cpp_type()) {
case FieldDescriptor::CPPTYPE_INT32: {
int32 value = _GetDescriptor(self)->default_value_int32();
int32_t value = _GetDescriptor(self)->default_value_int32();
result = PyInt_FromLong(value);
break;
}
case FieldDescriptor::CPPTYPE_INT64: {
int64 value = _GetDescriptor(self)->default_value_int64();
int64_t value = _GetDescriptor(self)->default_value_int64();
result = PyLong_FromLongLong(value);
break;
}
case FieldDescriptor::CPPTYPE_UINT32: {
uint32 value = _GetDescriptor(self)->default_value_uint32();
uint32_t value = _GetDescriptor(self)->default_value_uint32();
result = PyInt_FromSize_t(value);
break;
}
case FieldDescriptor::CPPTYPE_UINT64: {
uint64 value = _GetDescriptor(self)->default_value_uint64();
uint64_t value = _GetDescriptor(self)->default_value_uint64();
result = PyLong_FromUnsignedLongLong(value);
break;
}

@ -33,6 +33,8 @@
#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>
@ -164,7 +166,7 @@ bool PyDescriptorDatabase::FindAllExtensionNumbers(
return false;
}
Py_ssize_t size = PyList_Size(py_list.get());
int64 item_value;
int64_t item_value;
for (Py_ssize_t i = 0 ; i < size; ++i) {
ScopedPyObjectPtr item(PySequence_GetItem(py_list.get(), i));
item_value = PyLong_AsLong(item.get());

@ -176,9 +176,10 @@ static PyDescriptorPool* PyDescriptorPool_NewWithDatabase(
// The public DescriptorPool constructor.
static PyObject* New(PyTypeObject* type,
PyObject* args, PyObject* kwargs) {
static char* kwlist[] = {"descriptor_db", 0};
static const char* kwlist[] = {"descriptor_db", 0};
PyObject* py_database = NULL;
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O", kwlist, &py_database)) {
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O",
const_cast<char**>(kwlist), &py_database)) {
return NULL;
}
DescriptorDatabase* database = NULL;

@ -32,14 +32,16 @@
// Author: tibell@google.com (Johan Tibell)
#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/descriptor.pb.h>
#include <google/protobuf/pyext/descriptor.h>
#include <google/protobuf/pyext/message.h>
#include <google/protobuf/pyext/message_factory.h>
@ -263,7 +265,7 @@ PyObject* _FindExtensionByName(ExtensionDict* self, PyObject* arg) {
}
PyObject* _FindExtensionByNumber(ExtensionDict* self, PyObject* arg) {
int64 number = PyLong_AsLong(arg);
int64_t number = PyLong_AsLong(arg);
if (number == -1 && PyErr_Occurred()) {
return NULL;
}

@ -32,15 +32,16 @@
#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_field.h>
#include <google/protobuf/map.h>
#include <google/protobuf/map_field.h>
#include <google/protobuf/message.h>
#include <google/protobuf/pyext/message_factory.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>
@ -99,7 +100,7 @@ struct MapIterator {
//
// We store this so that if the map is modified during iteration we can throw
// an error.
uint64 version;
uint64_t version;
};
Message* MapContainer::GetMutableMessage() {
@ -462,10 +463,11 @@ int MapReflectionFriend::ScalarMapSetItem(PyObject* _self, PyObject* key,
static PyObject* ScalarMapGet(PyObject* self, PyObject* args,
PyObject* kwargs) {
static char* kwlist[] = {"key", "default", nullptr};
static const char* kwlist[] = {"key", "default", nullptr};
PyObject* key;
PyObject* default_value = NULL;
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O", kwlist, &key,
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O",
const_cast<char**>(kwlist), &key,
&default_value)) {
return NULL;
}
@ -757,10 +759,11 @@ PyObject* MapReflectionFriend::MessageMapToStr(PyObject* _self) {
}
PyObject* MessageMapGet(PyObject* self, PyObject* args, PyObject* kwargs) {
static char* kwlist[] = {"key", "default", nullptr};
static const char* kwlist[] = {"key", "default", nullptr};
PyObject* key;
PyObject* default_value = NULL;
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O", kwlist, &key,
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O",
const_cast<char**>(kwlist), &key,
&default_value)) {
return NULL;
}

@ -33,6 +33,7 @@
#include <Python.h>
#include <cstdint>
#include <memory>
#include <google/protobuf/descriptor.h>
@ -56,7 +57,7 @@ struct MapContainer : public ContainerBase {
// We bump this whenever we perform a mutation, to invalidate existing
// iterators.
uint64 version;
uint64_t version;
};
struct MessageMapContainer : public MapContainer {

@ -35,6 +35,7 @@
#include <structmember.h> // A Python header file.
#include <cstdint>
#include <map>
#include <memory>
#include <string>
@ -196,15 +197,14 @@ static int AddDescriptors(PyObject* cls, const Descriptor* descriptor) {
}
static PyObject* New(PyTypeObject* type, PyObject* args, PyObject* kwargs) {
static char *kwlist[] = {"name", "bases", "dict", 0};
static const char* kwlist[] = {"name", "bases", "dict", 0};
PyObject *bases, *dict;
const char* name;
// Check arguments: (name, bases, dict)
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "sO!O!:type", kwlist,
&name,
&PyTuple_Type, &bases,
&PyDict_Type, &dict)) {
if (!PyArg_ParseTupleAndKeywords(
args, kwargs, "sO!O!:type", const_cast<char**>(kwlist), &name,
&PyTuple_Type, &bases, &PyDict_Type, &dict)) {
return NULL;
}
@ -546,7 +546,7 @@ PyObject* PickleError_class;
// Format an error message for unexpected types.
// Always return with an exception set.
void FormatTypeError(PyObject* arg, char* expected_types) {
void FormatTypeError(PyObject* arg, const char* expected_types) {
// This function is often called with an exception set.
// Clear it to call PyObject_Repr() in good conditions.
PyErr_Clear();
@ -1679,10 +1679,10 @@ static PyObject* InternalSerializeToString(
CMessage* self, PyObject* args, PyObject* kwargs,
bool require_initialized) {
// Parse the "deterministic" kwarg; defaults to False.
static char* kwlist[] = { "deterministic", 0 };
static const char* kwlist[] = {"deterministic", 0};
PyObject* deterministic_obj = Py_None;
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O", kwlist,
&deterministic_obj)) {
if (!PyArg_ParseTupleAndKeywords(
args, kwargs, "|O", const_cast<char**>(kwlist), &deterministic_obj)) {
return NULL;
}
// Preemptively convert to a bool first, so we don't need to back out of
@ -1927,9 +1927,8 @@ PyObject* SetAllowOversizeProtos(PyObject* m, PyObject* arg) {
}
static PyObject* MergeFromString(CMessage* self, PyObject* arg) {
const void* data;
Py_ssize_t data_length;
if (PyObject_AsReadBuffer(arg, &data, &data_length) < 0) {
Py_buffer data;
if (PyObject_GetBuffer(arg, &data, PyBUF_SIMPLE) < 0) {
return NULL;
}
@ -1942,7 +1941,8 @@ static PyObject* MergeFromString(CMessage* self, PyObject* arg) {
const char* ptr;
internal::ParseContext ctx(
depth, false, &ptr,
StringPiece(static_cast<const char*>(data), data_length));
StringPiece(static_cast<const char*>(data.buf), data.len));
PyBuffer_Release(&data);
ctx.data().pool = factory->pool->pool;
ctx.data().factory = factory->message_factory;
@ -1968,9 +1968,9 @@ static PyObject* MergeFromString(CMessage* self, PyObject* arg) {
// TODO(jieluo): Raise error and return NULL instead.
// b/27494216
PyErr_Warn(nullptr, "Unexpected end-group tag: Not all data was converted");
return PyInt_FromLong(data_length - ctx.BytesUntilLimit(ptr));
return PyInt_FromLong(data.len - ctx.BytesUntilLimit(ptr));
}
return PyInt_FromLong(data_length);
return PyInt_FromLong(data.len);
}
static PyObject* ParseFromString(CMessage* self, PyObject* arg) {
@ -2191,22 +2191,22 @@ PyObject* InternalGetScalar(const Message* message,
PyObject* result = NULL;
switch (field_descriptor->cpp_type()) {
case FieldDescriptor::CPPTYPE_INT32: {
int32 value = reflection->GetInt32(*message, field_descriptor);
int32_t value = reflection->GetInt32(*message, field_descriptor);
result = PyInt_FromLong(value);
break;
}
case FieldDescriptor::CPPTYPE_INT64: {
int64 value = reflection->GetInt64(*message, field_descriptor);
int64_t value = reflection->GetInt64(*message, field_descriptor);
result = PyLong_FromLongLong(value);
break;
}
case FieldDescriptor::CPPTYPE_UINT32: {
uint32 value = reflection->GetUInt32(*message, field_descriptor);
uint32_t value = reflection->GetUInt32(*message, field_descriptor);
result = PyInt_FromSize_t(value);
break;
}
case FieldDescriptor::CPPTYPE_UINT64: {
uint64 value = reflection->GetUInt64(*message, field_descriptor);
uint64_t value = reflection->GetUInt64(*message, field_descriptor);
result = PyLong_FromUnsignedLongLong(value);
break;
}

@ -36,6 +36,7 @@
#include <Python.h>
#include <cstdint>
#include <memory>
#include <string>
#include <unordered_map>
@ -286,25 +287,25 @@ PyObject* SetAllowOversizeProtos(PyObject* m, PyObject* arg);
((field_descriptor)->label() == FieldDescriptor::LABEL_REPEATED)
#define GOOGLE_CHECK_GET_INT32(arg, value, err) \
int32 value; \
int32_t value; \
if (!CheckAndGetInteger(arg, &value)) { \
return err; \
}
#define GOOGLE_CHECK_GET_INT64(arg, value, err) \
int64 value; \
int64_t value; \
if (!CheckAndGetInteger(arg, &value)) { \
return err; \
}
#define GOOGLE_CHECK_GET_UINT32(arg, value, err) \
uint32 value; \
uint32_t value; \
if (!CheckAndGetInteger(arg, &value)) { \
return err; \
}
#define GOOGLE_CHECK_GET_UINT64(arg, value, err) \
uint64 value; \
uint64_t value; \
if (!CheckAndGetInteger(arg, &value)) { \
return err; \
}
@ -329,7 +330,7 @@ PyObject* SetAllowOversizeProtos(PyObject* m, PyObject* arg);
#define FULL_MODULE_NAME "google.protobuf.pyext._message"
void FormatTypeError(PyObject* arg, char* expected_types);
void FormatTypeError(PyObject* arg, const char* expected_types);
template<class T>
bool CheckAndGetInteger(PyObject* arg, T* value);
bool CheckAndGetDouble(PyObject* arg, double* value);

@ -77,9 +77,10 @@ PyMessageFactory* NewMessageFactory(PyTypeObject* type, PyDescriptorPool* pool)
}
PyObject* New(PyTypeObject* type, PyObject* args, PyObject* kwargs) {
static char* kwlist[] = {"pool", 0};
static const char* kwlist[] = {"pool", 0};
PyObject* pool = NULL;
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O", kwlist, &pool)) {
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O",
const_cast<char**>(kwlist), &pool)) {
return NULL;
}
ScopedPyObjectPtr owned_pool;

@ -33,6 +33,7 @@
#include <google/protobuf/pyext/repeated_scalar_container.h>
#include <cstdint>
#include <memory>
#include <google/protobuf/stubs/common.h>
@ -207,25 +208,25 @@ static PyObject* Item(PyObject* pself, Py_ssize_t index) {
PyObject* result = nullptr;
switch (field_descriptor->cpp_type()) {
case FieldDescriptor::CPPTYPE_INT32: {
int32 value =
int32_t value =
reflection->GetRepeatedInt32(*message, field_descriptor, index);
result = PyInt_FromLong(value);
break;
}
case FieldDescriptor::CPPTYPE_INT64: {
int64 value =
int64_t value =
reflection->GetRepeatedInt64(*message, field_descriptor, index);
result = PyLong_FromLongLong(value);
break;
}
case FieldDescriptor::CPPTYPE_UINT32: {
uint32 value =
uint32_t value =
reflection->GetRepeatedUInt32(*message, field_descriptor, index);
result = PyLong_FromLongLong(value);
break;
}
case FieldDescriptor::CPPTYPE_UINT64: {
uint64 value =
uint64_t value =
reflection->GetRepeatedUInt64(*message, field_descriptor, index);
result = PyLong_FromUnsignedLongLong(value);
break;

@ -567,8 +567,6 @@ class _Printer(object):
self.out.write(', ')
self.PrintFieldValue(field, value[-1])
self.out.write(']')
if self.force_colon:
self.out.write(':')
self.out.write(' ' if self.as_one_line else '\n')
def _PrintMessageFieldValue(self, value):
@ -1060,7 +1058,7 @@ class _Parser(object):
value_cpptype = field.message_type.fields_by_name['value'].cpp_type
if value_cpptype == descriptor.FieldDescriptor.CPPTYPE_MESSAGE:
value = getattr(message, field.name)[sub_message.key]
value.MergeFrom(sub_message.value)
value.CopyFrom(sub_message.value)
else:
getattr(message, field.name)[sub_message.key] = sub_message.value

@ -18,6 +18,7 @@ from setuptools import setup, Extension, find_packages
from distutils.command.build_py import build_py as _build_py
from distutils.command.clean import clean as _clean
from distutils.command.build_ext import build_ext as _build_ext
from distutils.spawn import find_executable
# Find the Protocol Compiler.
@ -157,6 +158,22 @@ class build_py(_build_py):
if not any(fnmatch.fnmatchcase(fil, pat=pat) for pat in exclude)]
class build_ext(_build_ext):
def get_ext_filename(self, ext_name):
# since python3.5, python extensions' shared libraries use a suffix that corresponds to the value
# of sysconfig.get_config_var('EXT_SUFFIX') and contains info about the architecture the library targets.
# E.g. on x64 linux the suffix is ".cpython-XYZ-x86_64-linux-gnu.so"
# When crosscompiling python wheels, we need to be able to override this suffix
# so that the resulting file name matches the target architecture and we end up with a well-formed
# wheel.
filename = _build_ext.get_ext_filename(self, ext_name)
orig_ext_suffix = sysconfig.get_config_var("EXT_SUFFIX")
new_ext_suffix = os.getenv("PROTOCOL_BUFFERS_OVERRIDE_EXT_SUFFIX")
if new_ext_suffix and filename.endswith(orig_ext_suffix):
filename = filename[:-len(orig_ext_suffix)] + new_ext_suffix
return filename
class test_conformance(_build_py):
target = 'test_python'
def run(self):
@ -279,8 +296,6 @@ if __name__ == '__main__':
"Programming Language :: Python :: 3.5",
"Programming Language :: Python :: 3.6",
"Programming Language :: Python :: 3.7",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
],
namespace_packages=['google'],
packages=find_packages(
@ -293,6 +308,7 @@ if __name__ == '__main__':
cmdclass={
'clean': clean,
'build_py': build_py,
'build_ext': build_ext,
'test_conformance': test_conformance,
},
install_requires=install_requires,

@ -14,10 +14,9 @@ setenv =
commands =
python setup.py -q build_py
python: python setup.py -q build
# --warnings_as_errors disabled until we update the Python C extension. See:
# https://github.com/protocolbuffers/protobuf/issues/7930
# cpp: python setup.py -q build --cpp_implementation --warnings_as_errors --compile_static_extension
cpp: python setup.py -q build --cpp_implementation --compile_static_extension
# --warnings_as_errors disabled for Python 2.7 because _POSIX_C_SOURCE and _XOPEN_SOURCE are redefined
py27-cpp: python setup.py -q build --cpp_implementation --compile_static_extension
py{33,34,35,36,37,38,39}-cpp: python setup.py -q build --cpp_implementation --warnings_as_errors --compile_static_extension
python: python setup.py -q test -q
cpp: python setup.py -q test -q --cpp_implementation
python: python setup.py -q test_conformance

@ -37,7 +37,7 @@
#include "message.h"
#include "repeated_field.h"
VALUE cError;
VALUE cParseError;
VALUE cTypeError;
const upb_fielddef* map_field_key(const upb_fielddef* field) {
@ -441,8 +441,10 @@ void Init_protobuf_c() {
Map_register(protobuf);
Message_register(protobuf);
cError = rb_const_get(protobuf, rb_intern("Error"));
cParseError = rb_const_get(protobuf, rb_intern("ParseError"));
rb_gc_register_mark_object(cParseError);
cTypeError = rb_const_get(protobuf, rb_intern("TypeError"));
rb_gc_register_mark_object(cTypeError);
rb_define_singleton_method(protobuf, "discard_unknown",
Google_Protobuf_discard_unknown, 1);

@ -30,7 +30,7 @@ endif
AM_CXXFLAGS = $(NO_OPT_CXXFLAGS) $(PROTOBUF_OPT_FLAG)
AM_LDFLAGS = $(PTHREAD_CFLAGS)
AM_LDFLAGS = $(PTHREAD_CFLAGS) ${LIBLOG_LIBS}
# If I say "dist_include_DATA", automake complains that $(includedir) is not
# a "legitimate" directory for DATA. Screw you, automake.

@ -68,10 +68,8 @@ const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable descriptor_table_google
schemas, file_default_instances, TableStruct_google_2fprotobuf_2fany_2eproto::offsets,
file_level_metadata_google_2fprotobuf_2fany_2eproto, file_level_enum_descriptors_google_2fprotobuf_2fany_2eproto, file_level_service_descriptors_google_2fprotobuf_2fany_2eproto,
};
PROTOBUF_ATTRIBUTE_WEAK ::PROTOBUF_NAMESPACE_ID::Metadata
descriptor_table_google_2fprotobuf_2fany_2eproto_metadata_getter(int index) {
::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors(&descriptor_table_google_2fprotobuf_2fany_2eproto);
return descriptor_table_google_2fprotobuf_2fany_2eproto.file_level_metadata[index];
PROTOBUF_ATTRIBUTE_WEAK const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable* descriptor_table_google_2fprotobuf_2fany_2eproto_getter() {
return &descriptor_table_google_2fprotobuf_2fany_2eproto;
}
// Force running AddDescriptors() at dynamic initialization time.
@ -165,7 +163,6 @@ const char* Any::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::intern
while (!ctx->Done(&ptr)) {
::PROTOBUF_NAMESPACE_ID::uint32 tag;
ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag);
CHK_(ptr);
switch (tag >> 3) {
// string type_url = 1;
case 1:
@ -186,7 +183,8 @@ const char* Any::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::intern
continue;
default: {
handle_unusual:
if ((tag & 7) == 4 || tag == 0) {
if ((tag == 0) || ((tag & 7) == 4)) {
CHK_(ptr);
ctx->SetLastTag(tag);
goto success;
}
@ -323,10 +321,11 @@ void Any::InternalSwap(Any* other) {
}
::PROTOBUF_NAMESPACE_ID::Metadata Any::GetMetadata() const {
return GetMetadataStatic();
return ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors(
&descriptor_table_google_2fprotobuf_2fany_2eproto_getter, &descriptor_table_google_2fprotobuf_2fany_2eproto_once,
file_level_metadata_google_2fprotobuf_2fany_2eproto[0]);
}
// @@protoc_insertion_point(namespace_scope)
PROTOBUF_NAMESPACE_CLOSE
PROTOBUF_NAMESPACE_OPEN

@ -53,7 +53,6 @@ struct PROTOBUF_EXPORT TableStruct_google_2fprotobuf_2fany_2eproto {
static const ::PROTOBUF_NAMESPACE_ID::uint32 offsets[];
};
extern PROTOBUF_EXPORT const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable descriptor_table_google_2fprotobuf_2fany_2eproto;
PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::Metadata descriptor_table_google_2fprotobuf_2fany_2eproto_metadata_getter(int index);
PROTOBUF_NAMESPACE_OPEN
class Any;
struct AnyDefaultTypeInternal;
@ -70,7 +69,7 @@ class PROTOBUF_EXPORT Any PROTOBUF_FINAL :
public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.Any) */ {
public:
inline Any() : Any(nullptr) {}
virtual ~Any();
~Any() override;
explicit constexpr Any(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);
Any(const Any& from);
@ -96,10 +95,10 @@ class PROTOBUF_EXPORT Any PROTOBUF_FINAL :
return GetDescriptor();
}
static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() {
return GetMetadataStatic().descriptor;
return default_instance().GetMetadata().descriptor;
}
static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() {
return GetMetadataStatic().reflection;
return default_instance().GetMetadata().reflection;
}
static const Any& default_instance() {
return *internal_default_instance();
@ -200,12 +199,6 @@ class PROTOBUF_EXPORT Any PROTOBUF_FINAL :
public:
::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final;
private:
static ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadataStatic() {
return ::descriptor_table_google_2fprotobuf_2fany_2eproto_metadata_getter(kIndexInFileMessages);
}
public:
// nested types ----------------------------------------------------
@ -218,10 +211,8 @@ class PROTOBUF_EXPORT Any PROTOBUF_FINAL :
// string type_url = 1;
void clear_type_url();
const std::string& type_url() const;
void set_type_url(const std::string& value);
void set_type_url(std::string&& value);
void set_type_url(const char* value);
void set_type_url(const char* value, size_t size);
template <typename ArgT0 = const std::string&, typename... ArgT>
void set_type_url(ArgT0&& arg0, ArgT... args);
std::string* mutable_type_url();
std::string* release_type_url();
void set_allocated_type_url(std::string* type_url);
@ -234,10 +225,8 @@ class PROTOBUF_EXPORT Any PROTOBUF_FINAL :
// bytes value = 2;
void clear_value();
const std::string& value() const;
void set_value(const std::string& value);
void set_value(std::string&& value);
void set_value(const char* value);
void set_value(const void* value, size_t size);
template <typename ArgT0 = const std::string&, typename... ArgT>
void set_value(ArgT0&& arg0, ArgT... args);
std::string* mutable_value();
std::string* release_value();
void set_allocated_value(std::string* value);
@ -279,8 +268,11 @@ inline const std::string& Any::type_url() const {
// @@protoc_insertion_point(field_get:google.protobuf.Any.type_url)
return _internal_type_url();
}
inline void Any::set_type_url(const std::string& value) {
_internal_set_type_url(value);
template <typename ArgT0, typename... ArgT>
PROTOBUF_ALWAYS_INLINE
inline void Any::set_type_url(ArgT0&& arg0, ArgT... args) {
type_url_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArena());
// @@protoc_insertion_point(field_set:google.protobuf.Any.type_url)
}
inline std::string* Any::mutable_type_url() {
@ -294,25 +286,6 @@ inline void Any::_internal_set_type_url(const std::string& value) {
type_url_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena());
}
inline void Any::set_type_url(std::string&& value) {
type_url_.Set(
::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::move(value), GetArena());
// @@protoc_insertion_point(field_set_rvalue:google.protobuf.Any.type_url)
}
inline void Any::set_type_url(const char* value) {
GOOGLE_DCHECK(value != nullptr);
type_url_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string(value), GetArena());
// @@protoc_insertion_point(field_set_char:google.protobuf.Any.type_url)
}
inline void Any::set_type_url(const char* value,
size_t size) {
type_url_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string(
reinterpret_cast<const char*>(value), size), GetArena());
// @@protoc_insertion_point(field_set_pointer:google.protobuf.Any.type_url)
}
inline std::string* Any::_internal_mutable_type_url() {
return type_url_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena());
@ -340,8 +313,11 @@ inline const std::string& Any::value() const {
// @@protoc_insertion_point(field_get:google.protobuf.Any.value)
return _internal_value();
}
inline void Any::set_value(const std::string& value) {
_internal_set_value(value);
template <typename ArgT0, typename... ArgT>
PROTOBUF_ALWAYS_INLINE
inline void Any::set_value(ArgT0&& arg0, ArgT... args) {
value_.SetBytes(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArena());
// @@protoc_insertion_point(field_set:google.protobuf.Any.value)
}
inline std::string* Any::mutable_value() {
@ -355,25 +331,6 @@ inline void Any::_internal_set_value(const std::string& value) {
value_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena());
}
inline void Any::set_value(std::string&& value) {
value_.Set(
::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::move(value), GetArena());
// @@protoc_insertion_point(field_set_rvalue:google.protobuf.Any.value)
}
inline void Any::set_value(const char* value) {
GOOGLE_DCHECK(value != nullptr);
value_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string(value), GetArena());
// @@protoc_insertion_point(field_set_char:google.protobuf.Any.value)
}
inline void Any::set_value(const void* value,
size_t size) {
value_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string(
reinterpret_cast<const char*>(value), size), GetArena());
// @@protoc_insertion_point(field_set_pointer:google.protobuf.Any.value)
}
inline std::string* Any::_internal_mutable_value() {
return value_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena());

@ -150,10 +150,8 @@ const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable descriptor_table_google
schemas, file_default_instances, TableStruct_google_2fprotobuf_2fapi_2eproto::offsets,
file_level_metadata_google_2fprotobuf_2fapi_2eproto, file_level_enum_descriptors_google_2fprotobuf_2fapi_2eproto, file_level_service_descriptors_google_2fprotobuf_2fapi_2eproto,
};
PROTOBUF_ATTRIBUTE_WEAK ::PROTOBUF_NAMESPACE_ID::Metadata
descriptor_table_google_2fprotobuf_2fapi_2eproto_metadata_getter(int index) {
::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors(&descriptor_table_google_2fprotobuf_2fapi_2eproto);
return descriptor_table_google_2fprotobuf_2fapi_2eproto.file_level_metadata[index];
PROTOBUF_ATTRIBUTE_WEAK const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable* descriptor_table_google_2fprotobuf_2fapi_2eproto_getter() {
return &descriptor_table_google_2fprotobuf_2fapi_2eproto;
}
// Force running AddDescriptors() at dynamic initialization time.
@ -270,7 +268,6 @@ const char* Api::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::intern
while (!ctx->Done(&ptr)) {
::PROTOBUF_NAMESPACE_ID::uint32 tag;
ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag);
CHK_(ptr);
switch (tag >> 3) {
// string name = 1;
case 1:
@ -343,7 +340,8 @@ const char* Api::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::intern
continue;
default: {
handle_unusual:
if ((tag & 7) == 4 || tag == 0) {
if ((tag == 0) || ((tag & 7) == 4)) {
CHK_(ptr);
ctx->SetLastTag(tag);
goto success;
}
@ -575,10 +573,11 @@ void Api::InternalSwap(Api* other) {
}
::PROTOBUF_NAMESPACE_ID::Metadata Api::GetMetadata() const {
return GetMetadataStatic();
return ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors(
&descriptor_table_google_2fprotobuf_2fapi_2eproto_getter, &descriptor_table_google_2fprotobuf_2fapi_2eproto_once,
file_level_metadata_google_2fprotobuf_2fapi_2eproto[0]);
}
// ===================================================================
class Method::_Internal {
@ -674,7 +673,6 @@ const char* Method::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::int
while (!ctx->Done(&ptr)) {
::PROTOBUF_NAMESPACE_ID::uint32 tag;
ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag);
CHK_(ptr);
switch (tag >> 3) {
// string name = 1;
case 1:
@ -739,7 +737,8 @@ const char* Method::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::int
continue;
default: {
handle_unusual:
if ((tag & 7) == 4 || tag == 0) {
if ((tag == 0) || ((tag & 7) == 4)) {
CHK_(ptr);
ctx->SetLastTag(tag);
goto success;
}
@ -968,10 +967,11 @@ void Method::InternalSwap(Method* other) {
}
::PROTOBUF_NAMESPACE_ID::Metadata Method::GetMetadata() const {
return GetMetadataStatic();
return ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors(
&descriptor_table_google_2fprotobuf_2fapi_2eproto_getter, &descriptor_table_google_2fprotobuf_2fapi_2eproto_once,
file_level_metadata_google_2fprotobuf_2fapi_2eproto[1]);
}
// ===================================================================
class Mixin::_Internal {
@ -1043,7 +1043,6 @@ const char* Mixin::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::inte
while (!ctx->Done(&ptr)) {
::PROTOBUF_NAMESPACE_ID::uint32 tag;
ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag);
CHK_(ptr);
switch (tag >> 3) {
// string name = 1;
case 1:
@ -1065,7 +1064,8 @@ const char* Mixin::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::inte
continue;
default: {
handle_unusual:
if ((tag & 7) == 4 || tag == 0) {
if ((tag == 0) || ((tag & 7) == 4)) {
CHK_(ptr);
ctx->SetLastTag(tag);
goto success;
}
@ -1206,10 +1206,11 @@ void Mixin::InternalSwap(Mixin* other) {
}
::PROTOBUF_NAMESPACE_ID::Metadata Mixin::GetMetadata() const {
return GetMetadataStatic();
return ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors(
&descriptor_table_google_2fprotobuf_2fapi_2eproto_getter, &descriptor_table_google_2fprotobuf_2fapi_2eproto_once,
file_level_metadata_google_2fprotobuf_2fapi_2eproto[2]);
}
// @@protoc_insertion_point(namespace_scope)
PROTOBUF_NAMESPACE_CLOSE
PROTOBUF_NAMESPACE_OPEN

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

Loading…
Cancel
Save