PROTOBUF_SYNC_PIPER
pull/7845/head
Joshua Haberman 4 years ago
commit f3cf99c0fb
  1. 2
      .github/workflows/codespell.yml
  2. 1
      BUILD
  3. 48
      CHANGES.txt
  4. 24
      Makefile.am
  5. 2
      Protobuf-C++.podspec
  6. 12
      benchmarks/js/js_benchmark.js
  7. 12
      benchmarks/protobuf.js/protobufjs_benchmark.js
  8. 2
      cmake/CMakeLists.txt
  9. 4
      cmake/protobuf-options.cmake
  10. 2
      configure.ac
  11. 4
      conformance/conformance.proto
  12. 2
      conformance/failure_list_php_c.txt
  13. 2
      conformance/failure_list_php_c_32.txt
  14. 3
      conformance/failure_list_ruby.txt
  15. 4
      csharp/src/Google.Protobuf.Conformance/Conformance.cs
  16. BIN
      csharp/src/Google.Protobuf.Test/testprotos.pb
  17. 4
      csharp/src/Google.Protobuf/UnknownField.cs
  18. 2
      csharp/src/Google.Protobuf/WellKnownTypes/Api.cs
  19. 2
      java/README.md
  20. 2
      java/compatibility_tests/v2.5.0/more_protos/src/proto/google/protobuf/descriptor.proto
  21. 2
      java/compatibility_tests/v2.5.0/protos/src/proto/google/protobuf/descriptor.proto
  22. 4
      java/core/src/main/java/com/google/protobuf/ArrayDecoders.java
  23. 2
      java/core/src/main/java/com/google/protobuf/Descriptors.java
  24. 2
      java/core/src/main/java/com/google/protobuf/GeneratedMessageLite.java
  25. 2
      java/core/src/main/java/com/google/protobuf/MapEntryLite.java
  26. 7
      java/core/src/test/java/com/google/protobuf/ExtensionRegistryFactoryTest.java
  27. 16
      java/lite.md
  28. 2
      js/binary/utils.js
  29. 2
      js/package.json
  30. 2
      objectivec/GPBApi.pbobjc.h
  31. 1
      protobuf.bzl
  32. 2
      python/compatibility_tests/v2.5.0/protos/src/proto/google/protobuf/descriptor.proto
  33. 2
      python/google/protobuf/__init__.py
  34. 5
      python/google/protobuf/descriptor.py
  35. 2
      python/google/protobuf/descriptor_database.py
  36. 2
      python/google/protobuf/internal/json_format_test.py
  37. 2
      python/google/protobuf/internal/message_test.py
  38. 4
      python/google/protobuf/internal/reflection_test.py
  39. 2
      python/google/protobuf/internal/well_known_types.py
  40. 2
      python/google/protobuf/pyext/scoped_pyobject_ptr.h
  41. 2
      src/Makefile.am
  42. 4
      src/google/protobuf/any.pb.h
  43. 4
      src/google/protobuf/api.pb.h
  44. 2
      src/google/protobuf/api.proto
  45. 2
      src/google/protobuf/arena_test_util.h
  46. 5
      src/google/protobuf/compiler/command_line_interface.cc
  47. 2
      src/google/protobuf/compiler/command_line_interface.h
  48. 7
      src/google/protobuf/compiler/cpp/cpp_helpers.cc
  49. 2
      src/google/protobuf/compiler/cpp/cpp_message.h
  50. 5
      src/google/protobuf/compiler/importer_unittest.cc
  51. 2
      src/google/protobuf/compiler/java/java_enum_field.cc
  52. 2
      src/google/protobuf/compiler/java/java_message_field.cc
  53. 2
      src/google/protobuf/compiler/java/java_primitive_field.cc
  54. 2
      src/google/protobuf/compiler/java/java_string_field.cc
  55. 2
      src/google/protobuf/compiler/js/js_generator.cc
  56. 4
      src/google/protobuf/compiler/js/js_generator.h
  57. 4
      src/google/protobuf/compiler/plugin.pb.h
  58. 2
      src/google/protobuf/compiler/python/python_generator.cc
  59. 2
      src/google/protobuf/descriptor.cc
  60. 4
      src/google/protobuf/descriptor.pb.h
  61. 2
      src/google/protobuf/descriptor_unittest.cc
  62. 4
      src/google/protobuf/duration.pb.h
  63. 4
      src/google/protobuf/empty.pb.h
  64. 4
      src/google/protobuf/field_mask.pb.h
  65. 11
      src/google/protobuf/generated_message_reflection.cc
  66. 2
      src/google/protobuf/generated_message_table_driven.h
  67. 4
      src/google/protobuf/io/coded_stream.h
  68. 2
      src/google/protobuf/io/zero_copy_stream_unittest.cc
  69. 2
      src/google/protobuf/map.h
  70. 26
      src/google/protobuf/map_field.cc
  71. 195
      src/google/protobuf/map_field.h
  72. 17
      src/google/protobuf/map_field_inl.h
  73. 2
      src/google/protobuf/map_field_lite.h
  74. 4
      src/google/protobuf/map_field_test.cc
  75. 13
      src/google/protobuf/map_test.cc
  76. 72
      src/google/protobuf/map_test_util.h
  77. 14
      src/google/protobuf/message.h
  78. 2
      src/google/protobuf/parse_context.cc
  79. 8
      src/google/protobuf/port_def.inc
  80. 4
      src/google/protobuf/source_context.pb.h
  81. 4
      src/google/protobuf/struct.pb.h
  82. 2
      src/google/protobuf/stubs/casts.h
  83. 2
      src/google/protobuf/stubs/common.cc
  84. 8
      src/google/protobuf/stubs/common.h
  85. 2
      src/google/protobuf/stubs/time_test.cc
  86. 4
      src/google/protobuf/text_format_unittest.cc
  87. 4
      src/google/protobuf/timestamp.pb.h
  88. 4
      src/google/protobuf/type.pb.h
  89. 6
      src/google/protobuf/util/field_mask_util.cc
  90. 2
      src/google/protobuf/util/internal/constants.h
  91. 2
      src/google/protobuf/util/internal/json_objectwriter.h
  92. 2
      src/google/protobuf/util/internal/json_stream_parser_test.cc
  93. 2
      src/google/protobuf/util/internal/type_info_test_helper.h
  94. 4
      src/google/protobuf/util/internal/utility.h
  95. 55
      src/google/protobuf/util/message_differencer.cc
  96. 2
      src/google/protobuf/util/message_differencer.h
  97. 14
      src/google/protobuf/wire_format.cc
  98. 4
      src/google/protobuf/wrappers.pb.h
  99. 19
      update_version.py

@ -12,5 +12,5 @@ jobs:
- uses: codespell-project/actions-codespell@master - uses: codespell-project/actions-codespell@master
with: with:
check_filenames: true check_filenames: true
skip: ./.git,./conformance/third_party,*.snk,*.pb,./src/google/protobuf/testdata,./objectivec/Tests,./python/compatibility_tests/v2.5.0/tests/google/protobuf/internal 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,fo,fundementals,hel,importd,inout,leapyear,nd,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,fo,fundementals,hel,importd,inout,leapyear,nd,ois,ons,parseable,process',te,testof,ue,unparseable,wasn,wee,gae,keyserver,objext,od"

@ -175,6 +175,7 @@ cc_library(
"src/google/protobuf/io/zero_copy_stream.cc", "src/google/protobuf/io/zero_copy_stream.cc",
"src/google/protobuf/io/zero_copy_stream_impl.cc", "src/google/protobuf/io/zero_copy_stream_impl.cc",
"src/google/protobuf/io/zero_copy_stream_impl_lite.cc", "src/google/protobuf/io/zero_copy_stream_impl_lite.cc",
"src/google/protobuf/map.cc",
"src/google/protobuf/message_lite.cc", "src/google/protobuf/message_lite.cc",
"src/google/protobuf/parse_context.cc", "src/google/protobuf/parse_context.cc",
"src/google/protobuf/repeated_field.cc", "src/google/protobuf/repeated_field.cc",

@ -1,4 +1,45 @@
2020-07-14 version 3.13.0-rc1 (C++/Java/Python/PHP/Objective-C/C#/Ruby/JavaScript) Unreleased Changes
Protocol Compiler
* The proto compiler no longer requires a .proto filename when it is not
generating code.
C++
* Arenas are now unconditionally enabled. cc_enable_arenas no longer has
any effect.
* Fix a memory corruption bug in reflection when mixing optional and
non-optional fields.
* Make SpaceUsed() calculation more thorough for map fields.
* Add stack overflow protection for text format with unknown field values.
* FieldPath::FollowAll() now returns a bool to signal if an out-of-bounds
error was encountered.
* Performance improvements for Map.
* Minor formatting fix when dumping a descriptor to .proto format with
DebugString.
* UBSAN fix in RepeatedField (#2073).
* When running under ASAN, skip a test that makes huge allocations.
* Fixed a crash that could happen when creating more than 256 extensions in
a single message.
Java
* Bugfix in mergeFrom() when a oneof has multiple message fields.
Python
* Print google.protobuf.NullValue as null instead of "NULL_VALUE" when it is
used outside WKT Value/Struct.
* Fix bug occurring when attempting to deep copy an enum type in python 3.
Go:
* Update go_package options to reference google.golang.org/protobuf module.
2020-07-14 version 3.13.0 (C++/Java/Python/PHP/Objective-C/C#/Ruby/JavaScript)
PHP:
* The C extension is completely rewritten. The new C extension has significantly
better parsing performance and fixes a handful of conformance issues. It will
also make it easier to add support for more features like proto2 and proto3 presence.
* The new C extension does not support PHP 5.x. PHP 5.x users can still use pure-PHP.
C++: C++:
* Removed deprecated unsafe arena string accessors * Removed deprecated unsafe arena string accessors
@ -51,6 +92,11 @@
performance (the legacy generated code will still work, but might incur performance (the legacy generated code will still work, but might incur
a slight performance penalty). a slight performance penalty).
2020-07-28 version 3.12.4 (C++/Java/Python/PHP/Objective-C/C#/Ruby/JavaScript)
This release contains no significant changes, but exists because 3.12.3 was
mistakenly tagged at the wrong commit.
2020-06-01 version 3.12.3 (C++/Java/Python/PHP/Objective-C/C#/Ruby/JavaScript) 2020-06-01 version 3.12.3 (C++/Java/Python/PHP/Objective-C/C#/Ruby/JavaScript)
Objective-C Objective-C

@ -551,13 +551,14 @@ java_EXTRA_DIST=
java/util/src/test/java/com/google/protobuf/util/FieldMaskTreeTest.java \ java/util/src/test/java/com/google/protobuf/util/FieldMaskTreeTest.java \
java/util/src/test/java/com/google/protobuf/util/FieldMaskUtilTest.java \ java/util/src/test/java/com/google/protobuf/util/FieldMaskUtilTest.java \
java/util/src/test/java/com/google/protobuf/util/JsonFormatTest.java \ java/util/src/test/java/com/google/protobuf/util/JsonFormatTest.java \
java/util/src/test/java/com/google/protobuf/util/StructsTest.java \ java/util/src/test/java/com/google/protobuf/util/StructsTest.java \
java/util/src/test/java/com/google/protobuf/util/TimeUtilTest.java \ java/util/src/test/java/com/google/protobuf/util/TimeUtilTest.java \
java/util/src/test/java/com/google/protobuf/util/ValuesTest.java \ java/util/src/test/java/com/google/protobuf/util/ValuesTest.java \
java/util/src/test/proto/com/google/protobuf/util/json_test.proto java/util/src/test/proto/com/google/protobuf/util/json_test.proto
objectivec_EXTRA_DIST= \ objectivec_EXTRA_DIST= \
objectivec/.clang-format \ objectivec/.clang-format \
objectivec/BUILD \
objectivec/DevTools/check_version_stamps.sh \ objectivec/DevTools/check_version_stamps.sh \
objectivec/DevTools/compile_testing_protos.sh \ objectivec/DevTools/compile_testing_protos.sh \
objectivec/DevTools/full_mac_build.sh \ objectivec/DevTools/full_mac_build.sh \
@ -915,23 +916,23 @@ php_EXTRA_DIST= \
php/src/Google/Protobuf/UInt64Value.php \ php/src/Google/Protobuf/UInt64Value.php \
php/src/Google/Protobuf/Value.php \ php/src/Google/Protobuf/Value.php \
php/src/phpdoc.dist.xml \ php/src/phpdoc.dist.xml \
php/tests/array_test.php \ php/tests/ArrayTest.php \
php/tests/autoload.php \ php/tests/autoload.php \
php/tests/bootstrap_phpunit.php \ php/tests/bootstrap_phpunit.php \
php/tests/compatibility_test.sh \ php/tests/compatibility_test.sh \
php/tests/compile_extension.sh \ php/tests/compile_extension.sh \
php/tests/descriptors_test.php \ php/tests/DescriptorsTest.php \
php/tests/encode_decode_test.php \ php/tests/EncodeDecodeTest.php \
php/tests/gdb_test.sh \ php/tests/gdb_test.sh \
php/tests/generate_protos.sh \ php/tests/generate_protos.sh \
php/tests/generated_class_test.php \ php/tests/GeneratedClassTest.php \
php/tests/generated_phpdoc_test.php \ php/tests/GeneratedPhpdocTest.php \
php/tests/generated_service_test.php \ php/tests/GeneratedServiceTest.php \
php/tests/map_field_test.php \ php/tests/MapFieldTest.php \
php/tests/memory_leak_test.php \ php/tests/memory_leak_test.php \
php/tests/multirequest.php \ php/tests/multirequest.php \
php/tests/multirequest.sh \ php/tests/multirequest.sh \
php/tests/php_implementation_test.php \ php/tests/PhpImplementationTest.php \
php/tests/proto/empty/echo.proto \ php/tests/proto/empty/echo.proto \
php/tests/proto/test.proto \ php/tests/proto/test.proto \
php/tests/proto/test_descriptors.proto \ php/tests/proto/test_descriptors.proto \
@ -954,8 +955,9 @@ php_EXTRA_DIST= \
php/tests/test_base.php \ php/tests/test_base.php \
php/tests/test_util.php \ php/tests/test_util.php \
php/tests/undefined_test.php \ php/tests/undefined_test.php \
php/tests/well_known_test.php \ php/tests/valgrind.supp \
php/tests/wrapper_type_setters_test.php php/tests/WellKnownTest.php \
php/tests/WrapperTypeSettersTest.php
python_EXTRA_DIST= \ python_EXTRA_DIST= \
python/MANIFEST.in \ python/MANIFEST.in \

@ -1,6 +1,6 @@
Pod::Spec.new do |s| Pod::Spec.new do |s|
s.name = 'Protobuf-C++' s.name = 'Protobuf-C++'
s.version = '3.12.3' s.version = '3.13.0'
s.summary = 'Protocol Buffers v3 runtime library for C++.' s.summary = 'Protocol Buffers v3 runtime library for C++.'
s.homepage = 'https://github.com/google/protobuf' s.homepage = 'https://github.com/google/protobuf'
s.license = '3-Clause BSD License' s.license = '3-Clause BSD License'

@ -41,9 +41,9 @@ process.argv.forEach(function(filename, index) {
totalBytes += onePayload.length; totalBytes += onePayload.length;
}); });
var senarios = benchmarkSuite.newBenchmark( var scenarios = benchmarkSuite.newBenchmark(
benchmarkDataset.getMessageName(), filename, "js"); benchmarkDataset.getMessageName(), filename, "js");
senarios.suite scenarios.suite
.add("js deserialize", function() { .add("js deserialize", function() {
benchmarkDataset.getPayloadList().forEach(function(onePayload) { benchmarkDataset.getPayloadList().forEach(function(onePayload) {
var protoType = getNewPrototype(benchmarkDataset.getMessageName()); var protoType = getNewPrototype(benchmarkDataset.getMessageName());
@ -61,15 +61,15 @@ process.argv.forEach(function(filename, index) {
results.push({ results.push({
filename: filename, filename: filename,
benchmarks: { benchmarks: {
protobufjs_decoding: senarios.benches[0] * totalBytes / 1024 / 1024, protobufjs_decoding: scenarios.benches[0] * totalBytes / 1024 / 1024,
protobufjs_encoding: senarios.benches[1] * totalBytes / 1024 / 1024 protobufjs_encoding: scenarios.benches[1] * totalBytes / 1024 / 1024
} }
}) })
console.log("Throughput for deserialize: " console.log("Throughput for deserialize: "
+ senarios.benches[0] * totalBytes / 1024 / 1024 + "MB/s" ); + scenarios.benches[0] * totalBytes / 1024 / 1024 + "MB/s" );
console.log("Throughput for serialize: " console.log("Throughput for serialize: "
+ senarios.benches[1] * totalBytes / 1024 / 1024 + "MB/s" ); + scenarios.benches[1] * totalBytes / 1024 / 1024 + "MB/s" );
console.log(""); console.log("");
}); });
console.log("#####################################################"); console.log("#####################################################");

@ -31,9 +31,9 @@ process.argv.forEach(function(filename, index) {
totalBytes += onePayload.length; totalBytes += onePayload.length;
}); });
var senarios = benchmarkSuite.newBenchmark( var scenarios = benchmarkSuite.newBenchmark(
benchmarkDataset.messageName, filename, "protobufjs"); benchmarkDataset.messageName, filename, "protobufjs");
senarios.suite scenarios.suite
.add("protobuf.js static decoding", function() { .add("protobuf.js static decoding", function() {
benchmarkDataset.payload.forEach(function(onePayload) { benchmarkDataset.payload.forEach(function(onePayload) {
var protoType = getNewPrototype(benchmarkDataset.messageName); var protoType = getNewPrototype(benchmarkDataset.messageName);
@ -51,15 +51,15 @@ process.argv.forEach(function(filename, index) {
results.push({ results.push({
filename: filename, filename: filename,
benchmarks: { benchmarks: {
protobufjs_decoding: senarios.benches[0] * totalBytes, protobufjs_decoding: scenarios.benches[0] * totalBytes,
protobufjs_encoding: senarios.benches[1] * totalBytes protobufjs_encoding: scenarios.benches[1] * totalBytes
} }
}) })
console.log("Throughput for decoding: " console.log("Throughput for decoding: "
+ senarios.benches[0] * totalBytes / 1024 / 1024 + "MB/s" ); + scenarios.benches[0] * totalBytes / 1024 / 1024 + "MB/s" );
console.log("Throughput for encoding: " console.log("Throughput for encoding: "
+ senarios.benches[1] * totalBytes / 1024 / 1024 + "MB/s" ); + scenarios.benches[1] * totalBytes / 1024 / 1024 + "MB/s" );
console.log(""); console.log("");
}); });
console.log("#####################################################"); console.log("#####################################################");

@ -29,7 +29,7 @@ else()
endif() endif()
# The Intel compiler isn't able to deal with noinline member functions of # The Intel compiler isn't able to deal with noinline member functions of
# template classses defined in headers. As such it spams the output with # template classes defined in headers. As such it spams the output with
# warning #2196: routine is both "inline" and "noinline" # warning #2196: routine is both "inline" and "noinline"
# This silences that warning. # This silences that warning.
if (CMAKE_CXX_COMPILER_ID MATCHES Intel) if (CMAKE_CXX_COMPILER_ID MATCHES Intel)

@ -2,6 +2,6 @@
option(protobuf_VERBOSE "Enable for verbose output" OFF) option(protobuf_VERBOSE "Enable for verbose output" OFF)
mark_as_advanced(protobuf_VERBOSE) mark_as_advanced(protobuf_VERBOSE)
# FindProtobuf module compatibel # FindProtobuf module compatible
option(protobuf_MODULE_COMPATIBLE "CMake build-in FindProtobuf.cmake module compatible" OFF) option(protobuf_MODULE_COMPATIBLE "CMake built-in FindProtobuf.cmake module compatible" OFF)
mark_as_advanced(protobuf_MODULE_COMPATIBLE) mark_as_advanced(protobuf_MODULE_COMPATIBLE)

@ -17,7 +17,7 @@ AC_PREREQ(2.59)
# In the SVN trunk, the version should always be the next anticipated release # In the SVN trunk, the version should always be the next anticipated release
# version with the "-pre" suffix. (We used to use "-SNAPSHOT" but this pushed # version with the "-pre" suffix. (We used to use "-SNAPSHOT" but this pushed
# the size of one file name in the dist tarfile over the 99-char limit.) # the size of one file name in the dist tarfile over the 99-char limit.)
AC_INIT([Protocol Buffers],[3.12.3],[protobuf@googlegroups.com],[protobuf]) AC_INIT([Protocol Buffers],[3.13.0],[protobuf@googlegroups.com],[protobuf])
AM_MAINTAINER_MODE([enable]) AM_MAINTAINER_MODE([enable])

@ -64,7 +64,7 @@ enum TestCategory {
BINARY_TEST = 1; // Test binary wire format. BINARY_TEST = 1; // Test binary wire format.
JSON_TEST = 2; // Test json wire format. JSON_TEST = 2; // Test json wire format.
// Similar to JSON_TEST. However, during parsing json, testee should ignore // Similar to JSON_TEST. However, during parsing json, testee should ignore
// unknown fields. This feature is optional. Each implementation can descide // unknown fields. This feature is optional. Each implementation can decide
// whether to support it. See // whether to support it. See
// https://developers.google.com/protocol-buffers/docs/proto3#json_options // https://developers.google.com/protocol-buffers/docs/proto3#json_options
// for more detail. // for more detail.
@ -113,7 +113,7 @@ message ConformanceRequest {
string message_type = 4; string message_type = 4;
// Each test is given a specific test category. Some category may need // Each test is given a specific test category. Some category may need
// spedific support in testee programs. Refer to the definition of TestCategory // specific support in testee programs. Refer to the definition of TestCategory
// for more information. // for more information.
TestCategory test_category = 5; TestCategory test_category = 5;

@ -1,2 +1,4 @@
Recommended.Proto2.JsonInput.FieldNameExtension.Validator Recommended.Proto2.JsonInput.FieldNameExtension.Validator
Recommended.Proto3.JsonInput.NullValueInOtherOneofNewFormat.Validator
Recommended.Proto3.JsonInput.NullValueInOtherOneofOldFormat.Validator
Required.Proto2.JsonInput.StoresDefaultPrimitive.Validator Required.Proto2.JsonInput.StoresDefaultPrimitive.Validator

@ -1,2 +1,4 @@
Recommended.Proto2.JsonInput.FieldNameExtension.Validator Recommended.Proto2.JsonInput.FieldNameExtension.Validator
Recommended.Proto3.JsonInput.NullValueInOtherOneofNewFormat.Validator
Recommended.Proto3.JsonInput.NullValueInOtherOneofOldFormat.Validator
Required.Proto2.JsonInput.StoresDefaultPrimitive.Validator Required.Proto2.JsonInput.StoresDefaultPrimitive.Validator

@ -8,6 +8,9 @@ Recommended.Proto3.JsonInput.DurationHas3FractionalDigits.Validator
Recommended.Proto3.JsonInput.DurationHas6FractionalDigits.Validator Recommended.Proto3.JsonInput.DurationHas6FractionalDigits.Validator
Recommended.Proto3.JsonInput.FieldMaskInvalidCharacter Recommended.Proto3.JsonInput.FieldMaskInvalidCharacter
Recommended.Proto3.JsonInput.MapFieldValueIsNull Recommended.Proto3.JsonInput.MapFieldValueIsNull
Recommended.Proto3.JsonInput.NullValueInNormalMessage.Validator
Recommended.Proto3.JsonInput.NullValueInOtherOneofNewFormat.Validator
Recommended.Proto3.JsonInput.NullValueInOtherOneofOldFormat.Validator
Recommended.Proto3.JsonInput.RepeatedFieldMessageElementIsNull Recommended.Proto3.JsonInput.RepeatedFieldMessageElementIsNull
Recommended.Proto3.JsonInput.RepeatedFieldPrimitiveElementIsNull Recommended.Proto3.JsonInput.RepeatedFieldPrimitiveElementIsNull
Recommended.Proto3.JsonInput.StringEndsWithEscapeChar Recommended.Proto3.JsonInput.StringEndsWithEscapeChar

@ -82,7 +82,7 @@ namespace Conformance {
[pbr::OriginalName("JSON_TEST")] JsonTest = 2, [pbr::OriginalName("JSON_TEST")] JsonTest = 2,
/// <summary> /// <summary>
/// Similar to JSON_TEST. However, during parsing json, testee should ignore /// Similar to JSON_TEST. However, during parsing json, testee should ignore
/// unknown fields. This feature is optional. Each implementation can descide /// unknown fields. This feature is optional. Each implementation can decide
/// whether to support it. See /// whether to support it. See
/// https://developers.google.com/protocol-buffers/docs/proto3#json_options /// https://developers.google.com/protocol-buffers/docs/proto3#json_options
/// for more detail. /// for more detail.
@ -414,7 +414,7 @@ namespace Conformance {
private global::Conformance.TestCategory testCategory_ = global::Conformance.TestCategory.UnspecifiedTest; private global::Conformance.TestCategory testCategory_ = global::Conformance.TestCategory.UnspecifiedTest;
/// <summary> /// <summary>
/// Each test is given a specific test category. Some category may need /// Each test is given a specific test category. Some category may need
/// spedific support in testee programs. Refer to the definition of TestCategory /// specific support in testee programs. Refer to the definition of TestCategory
/// for more information. /// for more information.
/// </summary> /// </summary>
[global::System.Diagnostics.DebuggerNonUserCodeAttribute] [global::System.Diagnostics.DebuggerNonUserCodeAttribute]

@ -209,13 +209,13 @@ namespace Google.Protobuf
/// <summary> /// <summary>
/// Returns a new list containing all of the given specified values from /// Returns a new list containing all of the given specified values from
/// both the <paramref name="current"/> and <paramref name="extras"/> lists. /// both the <paramref name="current"/> and <paramref name="extras"/> lists.
/// If <paramref name="current" /> is null and <paramref name="extras"/> is empty, /// If <paramref name="current" /> is null and <paramref name="extras"/> is null or empty,
/// null is returned. Otherwise, either a new list is created (if <paramref name="current" /> /// null is returned. Otherwise, either a new list is created (if <paramref name="current" />
/// is null) or the elements of <paramref name="extras"/> are added to <paramref name="current" />. /// is null) or the elements of <paramref name="extras"/> are added to <paramref name="current" />.
/// </summary> /// </summary>
private static List<T> AddAll<T>(List<T> current, IList<T> extras) private static List<T> AddAll<T>(List<T> current, IList<T> extras)
{ {
if (extras.Count == 0) if (extras == null || extras.Count == 0)
{ {
return current; return current;
} }

@ -918,7 +918,7 @@ namespace Google.Protobuf.WellKnownTypes {
/// The mixin construct implies that all methods in `AccessControl` are /// The mixin construct implies that all methods in `AccessControl` are
/// also declared with same name and request/response types in /// also declared with same name and request/response types in
/// `Storage`. A documentation generator or annotation processor will /// `Storage`. A documentation generator or annotation processor will
/// see the effective `Storage.GetAcl` method after inherting /// see the effective `Storage.GetAcl` method after inheriting
/// documentation and annotations as follows: /// documentation and annotations as follows:
/// ///
/// service Storage { /// service Storage {

@ -45,7 +45,7 @@ protobuf-java-util package:
If you are using Gradle, add the following to your `build.gradle` file's dependencies: If you are using Gradle, add the following to your `build.gradle` file's dependencies:
``` ```
compile 'com.google.protobuf:protobuf-java:3.11.0' implementation 'com.google.protobuf:protobuf-java:3.11.0'
``` ```
Again, be sure to check that the version number matches (or is newer than) the version number of protoc that you are using. Again, be sure to check that the version number matches (or is newer than) the version number of protoc that you are using.

@ -74,7 +74,7 @@ message FileDescriptorProto {
optional FileOptions options = 8; optional FileOptions options = 8;
// This field contains optional information about the original source code. // This field contains optional information about the original source code.
// You may safely remove this entire field whithout harming runtime // You may safely remove this entire field without harming runtime
// functionality of the descriptors -- the information is needed only by // functionality of the descriptors -- the information is needed only by
// development tools. // development tools.
optional SourceCodeInfo source_code_info = 9; optional SourceCodeInfo source_code_info = 9;

@ -74,7 +74,7 @@ message FileDescriptorProto {
optional FileOptions options = 8; optional FileOptions options = 8;
// This field contains optional information about the original source code. // This field contains optional information about the original source code.
// You may safely remove this entire field whithout harming runtime // You may safely remove this entire field without harming runtime
// functionality of the descriptors -- the information is needed only by // functionality of the descriptors -- the information is needed only by
// development tools. // development tools.
optional SourceCodeInfo source_code_info = 9; optional SourceCodeInfo source_code_info = 9;

@ -39,7 +39,7 @@ import java.io.IOException;
* Helper functions to decode protobuf wire format from a byte array. * Helper functions to decode protobuf wire format from a byte array.
* *
* <p>Note that these functions don't do boundary check on the byte array but instead rely on Java * <p>Note that these functions don't do boundary check on the byte array but instead rely on Java
* VM to check it. That means parsing rountines utilizing these functions must catch * VM to check it. That means parsing routines utilizing these functions must catch
* IndexOutOfBoundsException and convert it to protobuf's InvalidProtocolBufferException when * IndexOutOfBoundsException and convert it to protobuf's InvalidProtocolBufferException when
* crossing protobuf public API boundaries. * crossing protobuf public API boundaries.
*/ */
@ -51,7 +51,7 @@ final class ArrayDecoders {
* multiple values and let the function set the return value in this Registers instance instead. * multiple values and let the function set the return value in this Registers instance instead.
* *
* <p>TODO(xiaofeng): This could be merged into CodedInputStream or CodedInputStreamReader which * <p>TODO(xiaofeng): This could be merged into CodedInputStream or CodedInputStreamReader which
* is already being passed through all the parsing rountines. * is already being passed through all the parsing routines.
*/ */
static final class Registers { static final class Registers {
public int int1; public int int1;

@ -1084,7 +1084,7 @@ public final class Descriptors {
/** /**
* Does this field have the {@code [packed = true]} option or is this field packable in proto3 * Does this field have the {@code [packed = true]} option or is this field packable in proto3
* and not explicitly setted to unpacked? * and not explicitly set to unpacked?
*/ */
@Override @Override
public boolean isPacked() { public boolean isPacked() {

@ -223,7 +223,7 @@ public abstract class GeneratedMessageLite<
/** /**
* A method that implements different types of operations described in {@link MethodToInvoke}. * A method that implements different types of operations described in {@link MethodToInvoke}.
* Theses different kinds of operations are required to implement message-level operations for * These different kinds of operations are required to implement message-level operations for
* builders in the runtime. This method bundles those operations to reduce the generated methods * builders in the runtime. This method bundles those operations to reduce the generated methods
* count. * count.
* *

@ -192,7 +192,7 @@ public class MapEntryLite<K, V> {
} }
/** /**
* Parses an entry off of the input into the map. This helper avoids allocaton of a {@link * Parses an entry off of the input into the map. This helper avoids allocation of a {@link
* MapEntryLite} by parsing directly into the provided {@link MapFieldLite}. * MapEntryLite} by parsing directly into the provided {@link MapFieldLite}.
*/ */
public void parseInto( public void parseInto(

@ -41,6 +41,7 @@ import java.util.Set;
import junit.framework.Test; import junit.framework.Test;
import junit.framework.TestCase; import junit.framework.TestCase;
import junit.framework.TestSuite; import junit.framework.TestSuite;
import org.junit.Ignore;
/** /**
* Tests for {@link ExtensionRegistryFactory} and the {@link ExtensionRegistry} instances it * Tests for {@link ExtensionRegistryFactory} and the {@link ExtensionRegistry} instances it
@ -52,7 +53,13 @@ import junit.framework.TestSuite;
* *
* <p>The test mechanism employed here is based on the pattern in {@code * <p>The test mechanism employed here is based on the pattern in {@code
* com.google.common.util.concurrent.AbstractFutureFallbackAtomicHelperTest} * com.google.common.util.concurrent.AbstractFutureFallbackAtomicHelperTest}
*
* <p> This test is temporarily disabled due to what appears to be a subtle change to class loading
* behavior in Java 11. That seems to have broken the way the test uses a custom ClassLoader to
* exercise Lite functionality.
*/ */
@SuppressWarnings("JUnit4ClassUsedInJUnit3")
@Ignore
public class ExtensionRegistryFactoryTest extends TestCase { public class ExtensionRegistryFactoryTest extends TestCase {
// A classloader which blacklists some non-Lite classes. // A classloader which blacklists some non-Lite classes.

@ -34,6 +34,22 @@ protobuf Java runtime. If you are using Maven, use the following:
</dependency> </dependency>
``` ```
## R8 rule to make production app builds work
The Lite runtime internally uses reflection to avoid generating hashCode/equals/(de)serialization methods.
R8 by default obfuscates the field names, which makes the reflection fail causing exceptions of the form
`java.lang.RuntimeException: Field {NAME}_ for {CLASS} not found. Known fields are [ {FIELDS} ]` in MessageSchema.java.
There are open issues for this on the [protobuf Github project](https://github.com/protocolbuffers/protobuf/issues/6463) and [R8](https://issuetracker.google.com/issues/144631039).
Until the issues is resolved you need to add the following line to your `proguard-rules.pro` file inside your project:
```
-keep class * extends com.google.protobuf.GeneratedMessageLite { *; }
```
## Older versions
For the older version of Java Lite (v3.0.0), please refer to: For the older version of Java Lite (v3.0.0), please refer to:
https://github.com/protocolbuffers/protobuf/blob/javalite/java/lite.md https://github.com/protocolbuffers/protobuf/blob/javalite/java/lite.md

@ -258,7 +258,7 @@ jspb.utils.splitFloat64 = function(value) {
// Compute the least significant exponent needed to represent the magnitude of // Compute the least significant exponent needed to represent the magnitude of
// the value by repeadly dividing/multiplying by 2 until the magnitude // the value by repeadly dividing/multiplying by 2 until the magnitude
// crosses 2. While tempting to use log math to find the exponent, at the // crosses 2. While tempting to use log math to find the exponent, at the
// bounadaries of precision, the result can be off by one. // boundaries of precision, the result can be off by one.
var maxDoubleExponent = 1023; var maxDoubleExponent = 1023;
var minDoubleExponent = -1022; var minDoubleExponent = -1022;
var x = value; var x = value;

@ -1,6 +1,6 @@
{ {
"name": "google-protobuf", "name": "google-protobuf",
"version": "3.12.3", "version": "3.13.0",
"description": "Protocol Buffers for JavaScript", "description": "Protocol Buffers for JavaScript",
"main": "google-protobuf.js", "main": "google-protobuf.js",
"files": [ "files": [

@ -257,7 +257,7 @@ typedef GPB_ENUM(GPBMixin_FieldNumber) {
* The mixin construct implies that all methods in `AccessControl` are * The mixin construct implies that all methods in `AccessControl` are
* also declared with same name and request/response types in * also declared with same name and request/response types in
* `Storage`. A documentation generator or annotation processor will * `Storage`. A documentation generator or annotation processor will
* see the effective `Storage.GetAcl` method after inherting * see the effective `Storage.GetAcl` method after inheriting
* documentation and annotations as follows: * documentation and annotations as follows:
* *
* service Storage { * service Storage {

@ -352,6 +352,7 @@ def _internal_gen_well_known_protos_java_impl(ctx):
inputs = descriptors, inputs = descriptors,
outputs = [srcjar], outputs = [srcjar],
arguments = [args], arguments = [args],
use_default_shell_env = True,
) )
return [ return [

@ -74,7 +74,7 @@ message FileDescriptorProto {
optional FileOptions options = 8; optional FileOptions options = 8;
// This field contains optional information about the original source code. // This field contains optional information about the original source code.
// You may safely remove this entire field whithout harming runtime // You may safely remove this entire field without harming runtime
// functionality of the descriptors -- the information is needed only by // functionality of the descriptors -- the information is needed only by
// development tools. // development tools.
optional SourceCodeInfo source_code_info = 9; optional SourceCodeInfo source_code_info = 9;

@ -30,7 +30,7 @@
# Copyright 2007 Google Inc. All Rights Reserved. # Copyright 2007 Google Inc. All Rights Reserved.
__version__ = '3.12.3' __version__ = '3.13.0'
if __name__ != '__main__': if __name__ != '__main__':
try: try:

@ -227,7 +227,8 @@ class _NestedDescriptorBase(DescriptorBase):
proto: An empty proto instance from descriptor_pb2. proto: An empty proto instance from descriptor_pb2.
Raises: Raises:
Error: If self couldnt be serialized, due to to few constructor arguments. Error: If self couldn't be serialized, due to to few constructor
arguments.
""" """
if (self.file is not None and if (self.file is not None and
self._serialized_start is not None and self._serialized_start is not None and
@ -827,7 +828,7 @@ class ServiceDescriptor(_NestedDescriptorBase):
Args: Args:
name (str): Name of the method. name (str): Name of the method.
Returns: Returns:
MethodDescriptor or None: the desctiptor for the requested method, if MethodDescriptor or None: the descriptor for the requested method, if
found. found.
""" """
return self.methods_by_name.get(name, None) return self.methods_by_name.get(name, None)

@ -58,7 +58,7 @@ class DescriptorDatabase(object):
Raises: Raises:
DescriptorDatabaseConflictingDefinitionError: if an attempt is made to DescriptorDatabaseConflictingDefinitionError: if an attempt is made to
add a proto with the same name but different definition than an add a proto with the same name but different definition than an
exisiting proto in the database. existing proto in the database.
""" """
proto_name = file_desc_proto.name proto_name = file_desc_proto.name
if proto_name not in self._file_desc_protos_by_file: if proto_name not in self._file_desc_protos_by_file:

@ -1078,7 +1078,7 @@ class JsonFormatTest(JsonFormatBase):
json_format.ParseError, json_format.ParseError,
'Failed to parse value field: year (0 )?is out of range.', 'Failed to parse value field: year (0 )?is out of range.',
json_format.Parse, text, message) json_format.Parse, text, message)
# Time bigger than maxinum time. # Time bigger than maximum time.
message.value.seconds = 253402300800 message.value.seconds = 253402300800
self.assertRaisesRegexp( self.assertRaisesRegexp(
OverflowError, OverflowError,

@ -1059,7 +1059,7 @@ class MessageTest(unittest.TestCase):
self.assertIsInstance(m.optional_string, six.text_type) self.assertIsInstance(m.optional_string, six.text_type)
def testLongValuedSlice(self, message_module): def testLongValuedSlice(self, message_module):
"""It should be possible to use long-valued indicies in slices """It should be possible to use long-valued indices in slices.
This didn't used to work in the v2 C++ implementation. This didn't used to work in the v2 C++ implementation.
""" """

@ -2813,7 +2813,7 @@ class SerializationTest(unittest.TestCase):
proto2.MergeFromString(serialized)) proto2.MergeFromString(serialized))
def _CheckRaises(self, exc_class, callable_obj, exception): def _CheckRaises(self, exc_class, callable_obj, exception):
"""This method checks if the excpetion type and message are as expected.""" """This method checks if the exception type and message are as expected."""
try: try:
callable_obj() callable_obj()
except exc_class as ex: except exc_class as ex:
@ -3267,7 +3267,7 @@ class ClassAPITest(unittest.TestCase):
# conflicting message descriptors. # conflicting message descriptors.
def testParsingFlatClassWithExplicitClassDeclaration(self): def testParsingFlatClassWithExplicitClassDeclaration(self):
"""Test that the generated class can parse a flat message.""" """Test that the generated class can parse a flat message."""
# TODO(xiaofeng): This test fails with cpp implemetnation in the call # TODO(xiaofeng): This test fails with cpp implementation in the call
# of six.with_metaclass(). The other two callsites of with_metaclass # of six.with_metaclass(). The other two callsites of with_metaclass
# in this file are both excluded from cpp test, so it might be expected # in this file are both excluded from cpp test, so it might be expected
# to fail. Need someone more familiar with the python code to take a # to fail. Need someone more familiar with the python code to take a

@ -401,7 +401,7 @@ def _CheckDurationValid(seconds, nanos):
def _RoundTowardZero(value, divider): def _RoundTowardZero(value, divider):
"""Truncates the remainder part after division.""" """Truncates the remainder part after division."""
# For some languanges, the sign of the remainder is implementation # For some languages, the sign of the remainder is implementation
# dependent if any of the operands is negative. Here we enforce # dependent if any of the operands is negative. Here we enforce
# "rounded toward zero" semantics. For example, for (-5) / 2 an # "rounded toward zero" semantics. For example, for (-5) / 2 an
# implementation may give -3 as the result with the remainder being # implementation may give -3 as the result with the remainder being

@ -77,7 +77,7 @@ class ScopedPythonPtr {
PyObject* as_pyobject() const { return reinterpret_cast<PyObject*>(ptr_); } PyObject* as_pyobject() const { return reinterpret_cast<PyObject*>(ptr_); }
// Increments the reference count fo the current object. // Increments the reference count of the current object.
// Should not be called when no object is held. // Should not be called when no object is held.
void inc() const { Py_INCREF(ptr_); } void inc() const { Py_INCREF(ptr_); }

@ -18,7 +18,7 @@ else
PTHREAD_DEF = PTHREAD_DEF =
endif endif
PROTOBUF_VERSION = 23:3:0 PROTOBUF_VERSION = 24:0:0
if GCC if GCC
# Turn on all warnings except for sign comparison (we ignore sign comparison # Turn on all warnings except for sign comparison (we ignore sign comparison

@ -8,12 +8,12 @@
#include <string> #include <string>
#include <google/protobuf/port_def.inc> #include <google/protobuf/port_def.inc>
#if PROTOBUF_VERSION < 3012000 #if PROTOBUF_VERSION < 3013000
#error This file was generated by a newer version of protoc which is #error This file was generated by a newer version of protoc which is
#error incompatible with your Protocol Buffer headers. Please update #error incompatible with your Protocol Buffer headers. Please update
#error your headers. #error your headers.
#endif #endif
#if 3012003 < PROTOBUF_MIN_PROTOC_VERSION #if 3013000 < PROTOBUF_MIN_PROTOC_VERSION
#error This file was generated by an older version of protoc which is #error This file was generated by an older version of protoc which is
#error incompatible with your Protocol Buffer headers. Please #error incompatible with your Protocol Buffer headers. Please
#error regenerate this file with a newer version of protoc. #error regenerate this file with a newer version of protoc.

@ -8,12 +8,12 @@
#include <string> #include <string>
#include <google/protobuf/port_def.inc> #include <google/protobuf/port_def.inc>
#if PROTOBUF_VERSION < 3012000 #if PROTOBUF_VERSION < 3013000
#error This file was generated by a newer version of protoc which is #error This file was generated by a newer version of protoc which is
#error incompatible with your Protocol Buffer headers. Please update #error incompatible with your Protocol Buffer headers. Please update
#error your headers. #error your headers.
#endif #endif
#if 3012003 < PROTOBUF_MIN_PROTOC_VERSION #if 3013000 < PROTOBUF_MIN_PROTOC_VERSION
#error This file was generated by an older version of protoc which is #error This file was generated by an older version of protoc which is
#error incompatible with your Protocol Buffer headers. Please #error incompatible with your Protocol Buffer headers. Please
#error regenerate this file with a newer version of protoc. #error regenerate this file with a newer version of protoc.

@ -167,7 +167,7 @@ message Method {
// The mixin construct implies that all methods in `AccessControl` are // The mixin construct implies that all methods in `AccessControl` are
// also declared with same name and request/response types in // also declared with same name and request/response types in
// `Storage`. A documentation generator or annotation processor will // `Storage`. A documentation generator or annotation processor will
// see the effective `Storage.GetAcl` method after inherting // see the effective `Storage.GetAcl` method after inheriting
// documentation and annotations as follows: // documentation and annotations as follows:
// //
// service Storage { // service Storage {

@ -84,7 +84,7 @@ class NoHeapChecker {
private: private:
class NewDeleteCapture { class NewDeleteCapture {
public: public:
// TOOD(xiaofeng): Implement this for opensource protobuf. // TODO(xiaofeng): Implement this for opensource protobuf.
void Hook() {} void Hook() {}
void Unhook() {} void Unhook() {}
int alloc_count() { return 0; } int alloc_count() { return 0; }

@ -1531,7 +1531,7 @@ CommandLineInterface::ParseArgumentStatus CommandLineInterface::ParseArguments(
} }
// Check error cases that span multiple flag values. // Check error cases that span multiple flag values.
bool missing_proto_definitions; bool missing_proto_definitions = false;
switch (mode_) { switch (mode_) {
case MODE_COMPILE: case MODE_COMPILE:
missing_proto_definitions = input_files_.empty(); missing_proto_definitions = input_files_.empty();
@ -1555,6 +1555,9 @@ CommandLineInterface::ParseArgumentStatus CommandLineInterface::ParseArguments(
case MODE_PRINT: case MODE_PRINT:
missing_proto_definitions = missing_proto_definitions =
input_files_.empty() && descriptor_set_in_names_.empty(); input_files_.empty() && descriptor_set_in_names_.empty();
break;
default:
GOOGLE_LOG(FATAL) << "Unexpected mode: " << mode_;
} }
if (missing_proto_definitions) { if (missing_proto_definitions) {
std::cerr << "Missing input file." << std::endl; std::cerr << "Missing input file." << std::endl;

@ -104,7 +104,7 @@ class DiskSourceTree; // importer.h
// 2. protoc --proto_path=src foo.proto (virtual path relative to src) // 2. protoc --proto_path=src foo.proto (virtual path relative to src)
// //
// If a file path can be interpreted both as a physical file path and as a // If a file path can be interpreted both as a physical file path and as a
// relative virtual path, the physical file path takes precendence. // relative virtual path, the physical file path takes precedence.
// //
// For a full description of the command-line syntax, invoke it with --help. // For a full description of the command-line syntax, invoke it with --help.
class PROTOC_EXPORT CommandLineInterface { class PROTOC_EXPORT CommandLineInterface {

@ -1415,9 +1415,7 @@ class ParseLoopGenerator {
format_.Set("has_bits", "_has_bits_"); format_.Set("has_bits", "_has_bits_");
} }
if (descriptor->file()->options().cc_enable_arenas()) { format_("$p_ns$::Arena* arena = GetArena(); (void)arena;\n");
format_("$p_ns$::Arena* arena = GetArena(); (void)arena;\n");
}
GenerateParseLoop(descriptor, ordered_fields); GenerateParseLoop(descriptor, ordered_fields);
format_.Outdent(); format_.Outdent();
format_("success:\n"); format_("success:\n");
@ -1469,8 +1467,7 @@ class ParseLoopGenerator {
// Open source doesn't support other ctypes; // Open source doesn't support other ctypes;
ctype = field->options().ctype(); ctype = field->options().ctype();
} }
if (field->file()->options().cc_enable_arenas() && !field->is_repeated() && if (!field->is_repeated() && !options_.opensource_runtime &&
!options_.opensource_runtime &&
GetOptimizeFor(field->file(), options_) != FileOptions::LITE_RUNTIME && GetOptimizeFor(field->file(), options_) != FileOptions::LITE_RUNTIME &&
// For now only use arena string for strings with empty defaults. // For now only use arena string for strings with empty defaults.
field->default_value_string().empty() && field->default_value_string().empty() &&

@ -105,7 +105,7 @@ class MessageGenerator {
bool GenerateParseTable(io::Printer* printer, size_t offset, bool GenerateParseTable(io::Printer* printer, size_t offset,
size_t aux_offset); size_t aux_offset);
// Generate the field offsets array. Returns the a pair of the total numer // Generate the field offsets array. Returns the a pair of the total number
// of entries generated and the index of the first has_bit entry. // of entries generated and the index of the first has_bit entry.
std::pair<size_t, size_t> GenerateOffsets(io::Printer* printer); std::pair<size_t, size_t> GenerateOffsets(io::Printer* printer);
void GenerateSchema(io::Printer* printer, int offset, int has_offset); void GenerateSchema(io::Printer* printer, int offset, int has_offset);

@ -463,13 +463,14 @@ TEST_F(DiskSourceTreeTest, DiskFileToVirtualFileCanonicalization) {
source_tree_.DiskFileToVirtualFile("../../baz", &virtual_file, source_tree_.DiskFileToVirtualFile("../../baz", &virtual_file,
&shadowing_disk_file)); &shadowing_disk_file));
// "/foo" is not mapped (it should not be misintepreted as being under "."). // "/foo" is not mapped (it should not be misinterpreted as being under ".").
EXPECT_EQ(DiskSourceTree::NO_MAPPING, EXPECT_EQ(DiskSourceTree::NO_MAPPING,
source_tree_.DiskFileToVirtualFile("/foo", &virtual_file, source_tree_.DiskFileToVirtualFile("/foo", &virtual_file,
&shadowing_disk_file)); &shadowing_disk_file));
#ifdef WIN32 #ifdef WIN32
// "C:\foo" is not mapped (it should not be misintepreted as being under "."). // "C:\foo" is not mapped (it should not be misinterpreted as being under
// ".").
EXPECT_EQ(DiskSourceTree::NO_MAPPING, EXPECT_EQ(DiskSourceTree::NO_MAPPING,
source_tree_.DiskFileToVirtualFile("C:\\foo", &virtual_file, source_tree_.DiskFileToVirtualFile("C:\\foo", &virtual_file,
&shadowing_disk_file)); &shadowing_disk_file));

@ -712,7 +712,7 @@ void RepeatedImmutableEnumFieldGenerator::GenerateBuilderMembers(
// list is immutable. If it's immutable, the invariant is that it must // list is immutable. If it's immutable, the invariant is that it must
// either an instance of Collections.emptyList() or it's an ArrayList // either an instance of Collections.emptyList() or it's an ArrayList
// wrapped in a Collections.unmodifiableList() wrapper and nobody else has // wrapped in a Collections.unmodifiableList() wrapper and nobody else has
// a refererence to the underlying ArrayList. This invariant allows us to // a reference to the underlying ArrayList. This invariant allows us to
// share instances of lists between protocol buffers avoiding expensive // share instances of lists between protocol buffers avoiding expensive
// memory allocations. Note, immutable is a strong guarantee here -- not // memory allocations. Note, immutable is a strong guarantee here -- not
// just that the list cannot be modified via the reference but that the // just that the list cannot be modified via the reference but that the

@ -944,7 +944,7 @@ void RepeatedImmutableMessageFieldGenerator::GenerateBuilderMembers(
// list is immutable. If it's immutable, the invariant is that it must // list is immutable. If it's immutable, the invariant is that it must
// either an instance of Collections.emptyList() or it's an ArrayList // either an instance of Collections.emptyList() or it's an ArrayList
// wrapped in a Collections.unmodifiableList() wrapper and nobody else has // wrapped in a Collections.unmodifiableList() wrapper and nobody else has
// a refererence to the underlying ArrayList. This invariant allows us to // a reference to the underlying ArrayList. This invariant allows us to
// share instances of lists between protocol buffers avoiding expensive // share instances of lists between protocol buffers avoiding expensive
// memory allocations. Note, immutable is a strong guarantee here -- not // memory allocations. Note, immutable is a strong guarantee here -- not
// just that the list cannot be modified via the reference but that the // just that the list cannot be modified via the reference but that the

@ -703,7 +703,7 @@ void RepeatedImmutablePrimitiveFieldGenerator::GenerateBuilderMembers(
// list is immutable. If it's immutable, the invariant is that it must // list is immutable. If it's immutable, the invariant is that it must
// either an instance of Collections.emptyList() or it's an ArrayList // either an instance of Collections.emptyList() or it's an ArrayList
// wrapped in a Collections.unmodifiableList() wrapper and nobody else has // wrapped in a Collections.unmodifiableList() wrapper and nobody else has
// a refererence to the underlying ArrayList. This invariant allows us to // a reference to the underlying ArrayList. This invariant allows us to
// share instances of lists between protocol buffers avoiding expensive // share instances of lists between protocol buffers avoiding expensive
// memory allocations. Note, immutable is a strong guarantee here -- not // memory allocations. Note, immutable is a strong guarantee here -- not
// just that the list cannot be modified via the reference but that the // just that the list cannot be modified via the reference but that the

@ -801,7 +801,7 @@ void RepeatedImmutableStringFieldGenerator::GenerateBuilderMembers(
// list is immutable. If it's immutable, the invariant is that it must // list is immutable. If it's immutable, the invariant is that it must
// either an instance of Collections.emptyList() or it's an ArrayList // either an instance of Collections.emptyList() or it's an ArrayList
// wrapped in a Collections.unmodifiableList() wrapper and nobody else has // wrapped in a Collections.unmodifiableList() wrapper and nobody else has
// a refererence to the underlying ArrayList. This invariant allows us to // a reference to the underlying ArrayList. This invariant allows us to
// share instances of lists between protocol buffers avoiding expensive // share instances of lists between protocol buffers avoiding expensive
// memory allocations. Note, immutable is a strong guarantee here -- not // memory allocations. Note, immutable is a strong guarantee here -- not
// just that the list cannot be modified via the reference but that the // just that the list cannot be modified via the reference but that the

@ -1654,6 +1654,8 @@ void Generator::GenerateHeader(const GeneratorOptions& options,
" * @public\n" " * @public\n"
" */\n" " */\n"
"// GENERATED CODE -- DO NOT EDIT!\n" "// GENERATED CODE -- DO NOT EDIT!\n"
"/* eslint-disable */\n"
"// @ts-nocheck\n"
"\n"); "\n");
} }

@ -125,10 +125,10 @@ struct GeneratorOptions {
std::string extension; std::string extension;
// Create a separate output file for each input file? // Create a separate output file for each input file?
bool one_output_file_per_input_file; bool one_output_file_per_input_file;
// If true, we should append annotations as commen on the last line for // If true, we should append annotations as comments on the last line for
// generated .js file. Annotations used by tools like https://kythe.io // generated .js file. Annotations used by tools like https://kythe.io
// to provide cross-references between .js and .proto files. Annotations // to provide cross-references between .js and .proto files. Annotations
// are enced as base64 proto of GeneratedCodeInfo message (see // are encoded as base64 proto of GeneratedCodeInfo message (see
// descriptor.proto). // descriptor.proto).
bool annotate_code; bool annotate_code;
}; };

@ -8,12 +8,12 @@
#include <string> #include <string>
#include <google/protobuf/port_def.inc> #include <google/protobuf/port_def.inc>
#if PROTOBUF_VERSION < 3012000 #if PROTOBUF_VERSION < 3013000
#error This file was generated by a newer version of protoc which is #error This file was generated by a newer version of protoc which is
#error incompatible with your Protocol Buffer headers. Please update #error incompatible with your Protocol Buffer headers. Please update
#error your headers. #error your headers.
#endif #endif
#if 3012003 < PROTOBUF_MIN_PROTOC_VERSION #if 3013000 < PROTOBUF_MIN_PROTOC_VERSION
#error This file was generated by an older version of protoc which is #error This file was generated by an older version of protoc which is
#error incompatible with your Protocol Buffer headers. Please #error incompatible with your Protocol Buffer headers. Please
#error regenerate this file with a newer version of protoc. #error regenerate this file with a newer version of protoc.

@ -1067,7 +1067,7 @@ void Generator::FixContainingTypeInDescriptor(
} }
// Prints statements setting the message_type and enum_type fields in the // Prints statements setting the message_type and enum_type fields in the
// Python descriptor objects we've already output in ths file. We must // Python descriptor objects we've already output in the file. We must
// do this in a separate step due to circular references (otherwise, we'd // do this in a separate step due to circular references (otherwise, we'd
// just set everything in the initial assignment statements). // just set everything in the initial assignment statements).
void Generator::FixForeignFieldsInDescriptors() const { void Generator::FixForeignFieldsInDescriptors() const {

@ -6133,7 +6133,7 @@ void DescriptorBuilder::ValidateFieldOptions(
// json_name option is not allowed on extension fields. Note that the // json_name option is not allowed on extension fields. Note that the
// json_name field in FieldDescriptorProto is always populated by protoc // json_name field in FieldDescriptorProto is always populated by protoc
// when it sends descriptor data to plugins (caculated from field name if // when it sends descriptor data to plugins (calculated from field name if
// the option is not explicitly set) so we can't rely on its presence to // the option is not explicitly set) so we can't rely on its presence to
// determine whether the json_name option is set on the field. Here we // determine whether the json_name option is set on the field. Here we
// compare it against the default calculated json_name value and consider // compare it against the default calculated json_name value and consider

@ -8,12 +8,12 @@
#include <string> #include <string>
#include <google/protobuf/port_def.inc> #include <google/protobuf/port_def.inc>
#if PROTOBUF_VERSION < 3012000 #if PROTOBUF_VERSION < 3013000
#error This file was generated by a newer version of protoc which is #error This file was generated by a newer version of protoc which is
#error incompatible with your Protocol Buffer headers. Please update #error incompatible with your Protocol Buffer headers. Please update
#error your headers. #error your headers.
#endif #endif
#if 3012003 < PROTOBUF_MIN_PROTOC_VERSION #if 3013000 < PROTOBUF_MIN_PROTOC_VERSION
#error This file was generated by an older version of protoc which is #error This file was generated by an older version of protoc which is
#error incompatible with your Protocol Buffer headers. Please #error incompatible with your Protocol Buffer headers. Please
#error regenerate this file with a newer version of protoc. #error regenerate this file with a newer version of protoc.

@ -479,7 +479,7 @@ TEST_F(FileDescriptorTest, FindExtensionByNumber) {
TEST_F(FileDescriptorTest, BuildAgain) { TEST_F(FileDescriptorTest, BuildAgain) {
// Test that if te call BuildFile again on the same input we get the same // Test that if we call BuildFile again on the same input we get the same
// FileDescriptor back. // FileDescriptor back.
FileDescriptorProto file; FileDescriptorProto file;
foo_file_->CopyTo(&file); foo_file_->CopyTo(&file);

@ -8,12 +8,12 @@
#include <string> #include <string>
#include <google/protobuf/port_def.inc> #include <google/protobuf/port_def.inc>
#if PROTOBUF_VERSION < 3012000 #if PROTOBUF_VERSION < 3013000
#error This file was generated by a newer version of protoc which is #error This file was generated by a newer version of protoc which is
#error incompatible with your Protocol Buffer headers. Please update #error incompatible with your Protocol Buffer headers. Please update
#error your headers. #error your headers.
#endif #endif
#if 3012003 < PROTOBUF_MIN_PROTOC_VERSION #if 3013000 < PROTOBUF_MIN_PROTOC_VERSION
#error This file was generated by an older version of protoc which is #error This file was generated by an older version of protoc which is
#error incompatible with your Protocol Buffer headers. Please #error incompatible with your Protocol Buffer headers. Please
#error regenerate this file with a newer version of protoc. #error regenerate this file with a newer version of protoc.

@ -8,12 +8,12 @@
#include <string> #include <string>
#include <google/protobuf/port_def.inc> #include <google/protobuf/port_def.inc>
#if PROTOBUF_VERSION < 3012000 #if PROTOBUF_VERSION < 3013000
#error This file was generated by a newer version of protoc which is #error This file was generated by a newer version of protoc which is
#error incompatible with your Protocol Buffer headers. Please update #error incompatible with your Protocol Buffer headers. Please update
#error your headers. #error your headers.
#endif #endif
#if 3012003 < PROTOBUF_MIN_PROTOC_VERSION #if 3013000 < PROTOBUF_MIN_PROTOC_VERSION
#error This file was generated by an older version of protoc which is #error This file was generated by an older version of protoc which is
#error incompatible with your Protocol Buffer headers. Please #error incompatible with your Protocol Buffer headers. Please
#error regenerate this file with a newer version of protoc. #error regenerate this file with a newer version of protoc.

@ -8,12 +8,12 @@
#include <string> #include <string>
#include <google/protobuf/port_def.inc> #include <google/protobuf/port_def.inc>
#if PROTOBUF_VERSION < 3012000 #if PROTOBUF_VERSION < 3013000
#error This file was generated by a newer version of protoc which is #error This file was generated by a newer version of protoc which is
#error incompatible with your Protocol Buffer headers. Please update #error incompatible with your Protocol Buffer headers. Please update
#error your headers. #error your headers.
#endif #endif
#if 3012003 < PROTOBUF_MIN_PROTOC_VERSION #if 3013000 < PROTOBUF_MIN_PROTOC_VERSION
#error This file was generated by an older version of protoc which is #error This file was generated by an older version of protoc which is
#error incompatible with your Protocol Buffer headers. Please #error incompatible with your Protocol Buffer headers. Please
#error regenerate this file with a newer version of protoc. #error regenerate this file with a newer version of protoc.

@ -853,7 +853,7 @@ void Reflection::ClearField(Message* message,
} }
case FieldDescriptor::CPPTYPE_MESSAGE: case FieldDescriptor::CPPTYPE_MESSAGE:
if (!schema_.HasHasbits()) { if (schema_.HasBitIndex(field) == -1) {
// Proto3 does not have has-bits and we need to set a message field // Proto3 does not have has-bits and we need to set a message field
// to nullptr in order to indicate its un-presence. // to nullptr in order to indicate its un-presence.
if (GetArena(message) == nullptr) { if (GetArena(message) == nullptr) {
@ -1884,6 +1884,15 @@ bool Reflection::InsertOrLookupMapValue(Message* message,
->InsertOrLookupMapValue(key, val); ->InsertOrLookupMapValue(key, val);
} }
bool Reflection::LookupMapValue(const Message& message,
const FieldDescriptor* field, const MapKey& key,
MapValueConstRef* val) const {
USAGE_CHECK(IsMapFieldInApi(field), "LookupMapValue",
"Field is not a map field.");
val->SetType(field->message_type()->FindFieldByName("value")->cpp_type());
return GetRaw<MapFieldBase>(message, field).LookupMapValue(key, val);
}
bool Reflection::DeleteMapValue(Message* message, const FieldDescriptor* field, bool Reflection::DeleteMapValue(Message* message, const FieldDescriptor* field,
const MapKey& key) const { const MapKey& key) const {
USAGE_CHECK(IsMapFieldInApi(field), "DeleteMapValue", USAGE_CHECK(IsMapFieldInApi(field), "DeleteMapValue",

@ -102,7 +102,7 @@ struct PROTOBUF_EXPORT FieldMetadata {
kNumTypeClasses // must be last enum kNumTypeClasses // must be last enum
}; };
// C++ protobuf has 20 fundamental types, were we added Cord and StringPiece // C++ protobuf has 20 fundamental types, were we added Cord and StringPiece
// and also distinquish the same types if they have different wire format. // and also distinguish the same types if they have different wire format.
enum { enum {
kCordType = 19, kCordType = 19,
kStringPieceType = 20, kStringPieceType = 20,

@ -960,7 +960,7 @@ class PROTOBUF_EXPORT EpsCopyOutputStream {
// buffers to ensure there is no error as of yet. // buffers to ensure there is no error as of yet.
uint8* FlushAndResetBuffer(uint8*); uint8* FlushAndResetBuffer(uint8*);
// The following functions mimick the old CodedOutputStream behavior as close // The following functions mimic the old CodedOutputStream behavior as close
// as possible. They flush the current state to the stream, behave as // as possible. They flush the current state to the stream, behave as
// the old CodedOutputStream and then return to normal operation. // the old CodedOutputStream and then return to normal operation.
bool Skip(int count, uint8** pp); bool Skip(int count, uint8** pp);
@ -1159,7 +1159,7 @@ class PROTOBUF_EXPORT CodedOutputStream {
// This is identical to WriteVarint32(), but optimized for writing tags. // This is identical to WriteVarint32(), but optimized for writing tags.
// In particular, if the input is a compile-time constant, this method // In particular, if the input is a compile-time constant, this method
// compiles down to a couple instructions. // compiles down to a couple instructions.
// Always inline because otherwise the aformentioned optimization can't work, // Always inline because otherwise the aforementioned optimization can't work,
// but GCC by default doesn't want to inline this. // but GCC by default doesn't want to inline this.
void WriteTag(uint32 value); void WriteTag(uint32 value);
// Like WriteTag() but writing directly to the target array. // Like WriteTag() but writing directly to the target array.

@ -112,7 +112,7 @@ class IoTest : public testing::Test {
// that it matches the string. // that it matches the string.
void ReadString(ZeroCopyInputStream* input, const std::string& str); void ReadString(ZeroCopyInputStream* input, const std::string& str);
// Writes some text to the output stream in a particular order. Returns // Writes some text to the output stream in a particular order. Returns
// the number of bytes written, incase the caller needs that to set up an // the number of bytes written, in case the caller needs that to set up an
// input stream. // input stream.
int WriteStuff(ZeroCopyOutputStream* output); int WriteStuff(ZeroCopyOutputStream* output);
// Reads text from an input stream and expects it to match what // Reads text from an input stream and expects it to match what

@ -445,7 +445,7 @@ class Map {
// 9. Except for erase(iterator), any non-const method can reorder iterators. // 9. Except for erase(iterator), any non-const method can reorder iterators.
// 10. InnerMap uses KeyForTree<Key> when using the Tree representation, which // 10. InnerMap uses KeyForTree<Key> when using the Tree representation, which
// is either `Key`, if Key is a scalar, or `reference_wrapper<const Key>` // is either `Key`, if Key is a scalar, or `reference_wrapper<const Key>`
// otherwise. This avoids unncessary copies of string keys, for example. // otherwise. This avoids unnecessary copies of string keys, for example.
class InnerMap : private hasher { class InnerMap : private hasher {
public: public:
explicit InnerMap(Arena* arena) explicit InnerMap(Arena* arena)

@ -44,20 +44,24 @@ MapFieldBase::~MapFieldBase() {
} }
const RepeatedPtrFieldBase& MapFieldBase::GetRepeatedField() const { const RepeatedPtrFieldBase& MapFieldBase::GetRepeatedField() const {
ConstAccess();
SyncRepeatedFieldWithMap(); SyncRepeatedFieldWithMap();
return *reinterpret_cast<RepeatedPtrFieldBase*>(repeated_field_); return *reinterpret_cast<RepeatedPtrFieldBase*>(repeated_field_);
} }
RepeatedPtrFieldBase* MapFieldBase::MutableRepeatedField() { RepeatedPtrFieldBase* MapFieldBase::MutableRepeatedField() {
MutableAccess();
SyncRepeatedFieldWithMap(); SyncRepeatedFieldWithMap();
SetRepeatedDirty(); SetRepeatedDirty();
return reinterpret_cast<RepeatedPtrFieldBase*>(repeated_field_); return reinterpret_cast<RepeatedPtrFieldBase*>(repeated_field_);
} }
size_t MapFieldBase::SpaceUsedExcludingSelfLong() const { size_t MapFieldBase::SpaceUsedExcludingSelfLong() const {
ConstAccess();
mutex_.Lock(); mutex_.Lock();
size_t size = SpaceUsedExcludingSelfNoLock(); size_t size = SpaceUsedExcludingSelfNoLock();
mutex_.Unlock(); mutex_.Unlock();
ConstAccess();
return size; return size;
} }
@ -70,6 +74,7 @@ size_t MapFieldBase::SpaceUsedExcludingSelfNoLock() const {
} }
bool MapFieldBase::IsMapValid() const { bool MapFieldBase::IsMapValid() const {
ConstAccess();
// "Acquire" insures the operation after SyncRepeatedFieldWithMap won't get // "Acquire" insures the operation after SyncRepeatedFieldWithMap won't get
// executed before state_ is checked. // executed before state_ is checked.
int state = state_.load(std::memory_order_acquire); int state = state_.load(std::memory_order_acquire);
@ -77,23 +82,27 @@ bool MapFieldBase::IsMapValid() const {
} }
bool MapFieldBase::IsRepeatedFieldValid() const { bool MapFieldBase::IsRepeatedFieldValid() const {
ConstAccess();
int state = state_.load(std::memory_order_acquire); int state = state_.load(std::memory_order_acquire);
return state != STATE_MODIFIED_MAP; return state != STATE_MODIFIED_MAP;
} }
void MapFieldBase::SetMapDirty() { void MapFieldBase::SetMapDirty() {
MutableAccess();
// These are called by (non-const) mutator functions. So by our API it's the // These are called by (non-const) mutator functions. So by our API it's the
// callers responsibility to have these calls properly ordered. // callers responsibility to have these calls properly ordered.
state_.store(STATE_MODIFIED_MAP, std::memory_order_relaxed); state_.store(STATE_MODIFIED_MAP, std::memory_order_relaxed);
} }
void MapFieldBase::SetRepeatedDirty() { void MapFieldBase::SetRepeatedDirty() {
MutableAccess();
// These are called by (non-const) mutator functions. So by our API it's the // These are called by (non-const) mutator functions. So by our API it's the
// callers responsibility to have these calls properly ordered. // callers responsibility to have these calls properly ordered.
state_.store(STATE_MODIFIED_REPEATED, std::memory_order_relaxed); state_.store(STATE_MODIFIED_REPEATED, std::memory_order_relaxed);
} }
void MapFieldBase::SyncRepeatedFieldWithMap() const { void MapFieldBase::SyncRepeatedFieldWithMap() const {
ConstAccess();
// acquire here matches with release below to ensure that we can only see a // acquire here matches with release below to ensure that we can only see a
// value of CLEAN after all previous changes have been synced. // value of CLEAN after all previous changes have been synced.
switch (state_.load(std::memory_order_acquire)) { switch (state_.load(std::memory_order_acquire)) {
@ -106,6 +115,7 @@ void MapFieldBase::SyncRepeatedFieldWithMap() const {
state_.store(CLEAN, std::memory_order_release); state_.store(CLEAN, std::memory_order_release);
} }
mutex_.Unlock(); mutex_.Unlock();
ConstAccess();
break; break;
case CLEAN: case CLEAN:
mutex_.Lock(); mutex_.Lock();
@ -122,6 +132,7 @@ void MapFieldBase::SyncRepeatedFieldWithMap() const {
state_.store(CLEAN, std::memory_order_release); state_.store(CLEAN, std::memory_order_release);
} }
mutex_.Unlock(); mutex_.Unlock();
ConstAccess();
break; break;
default: default:
break; break;
@ -135,6 +146,7 @@ void MapFieldBase::SyncRepeatedFieldWithMapNoLock() const {
} }
void MapFieldBase::SyncMapWithRepeatedField() const { void MapFieldBase::SyncMapWithRepeatedField() const {
ConstAccess();
// acquire here matches with release below to ensure that we can only see a // acquire here matches with release below to ensure that we can only see a
// value of CLEAN after all previous changes have been synced. // value of CLEAN after all previous changes have been synced.
if (state_.load(std::memory_order_acquire) == STATE_MODIFIED_REPEATED) { if (state_.load(std::memory_order_acquire) == STATE_MODIFIED_REPEATED) {
@ -146,6 +158,7 @@ void MapFieldBase::SyncMapWithRepeatedField() const {
state_.store(CLEAN, std::memory_order_release); state_.store(CLEAN, std::memory_order_release);
} }
mutex_.Unlock(); mutex_.Unlock();
ConstAccess();
} }
} }
@ -245,6 +258,19 @@ bool DynamicMapField::InsertOrLookupMapValue(const MapKey& map_key,
return false; return false;
} }
bool DynamicMapField::LookupMapValue(const MapKey& map_key,
MapValueConstRef* val) const {
const Map<MapKey, MapValueRef>& map = GetMap();
Map<MapKey, MapValueRef>::const_iterator iter = map.find(map_key);
if (iter == map.end()) {
return false;
}
// map_key is already in the map. Make sure (*map)[map_key] is not called.
// [] may reorder the map and iterators.
val->CopyFrom(iter->second);
return true;
}
bool DynamicMapField::DeleteMapValue(const MapKey& map_key) { bool DynamicMapField::DeleteMapValue(const MapKey& map_key) {
MapFieldBase::SyncMapWithRepeatedField(); MapFieldBase::SyncMapWithRepeatedField();
Map<MapKey, MapValueRef>::iterator iter = map_.find(map_key); Map<MapKey, MapValueRef>::iterator iter = map_.find(map_key);

@ -319,7 +319,7 @@ class MapFieldAccessor;
// This class provides access to map field using reflection, which is the same // This class provides access to map field using reflection, which is the same
// as those provided for RepeatedPtrField<Message>. It is used for internal // as those provided for RepeatedPtrField<Message>. It is used for internal
// reflection implentation only. Users should never use this directly. // reflection implementation only. Users should never use this directly.
class PROTOBUF_EXPORT MapFieldBase { class PROTOBUF_EXPORT MapFieldBase {
public: public:
MapFieldBase() MapFieldBase()
@ -346,6 +346,10 @@ class PROTOBUF_EXPORT MapFieldBase {
virtual bool ContainsMapKey(const MapKey& map_key) const = 0; virtual bool ContainsMapKey(const MapKey& map_key) const = 0;
virtual bool InsertOrLookupMapValue(const MapKey& map_key, virtual bool InsertOrLookupMapValue(const MapKey& map_key,
MapValueRef* val) = 0; MapValueRef* val) = 0;
virtual bool LookupMapValue(const MapKey& map_key,
MapValueConstRef* val) const = 0;
bool LookupMapValue(const MapKey&, MapValueRef*) const = delete;
// Returns whether changes to the map are reflected in the repeated field. // Returns whether changes to the map are reflected in the repeated field.
bool IsRepeatedFieldValid() const; bool IsRepeatedFieldValid() const;
// Insures operations after won't get executed before calling this. // Insures operations after won't get executed before calling this.
@ -386,12 +390,31 @@ class PROTOBUF_EXPORT MapFieldBase {
// Tells MapFieldBase that there is new change to Map. // Tells MapFieldBase that there is new change to Map.
void SetMapDirty(); void SetMapDirty();
// Tells MapFieldBase that there is new change to RepeatedPTrField. // Tells MapFieldBase that there is new change to RepeatedPtrField.
void SetRepeatedDirty(); void SetRepeatedDirty();
// Provides derived class the access to repeated field. // Provides derived class the access to repeated field.
void* MutableRepeatedPtrField() const; void* MutableRepeatedPtrField() const;
// Support thread sanitizer (tsan) by making const / mutable races
// more apparent. If one thread calls MutableAccess() while another
// thread calls either ConstAccess() or MutableAccess(), on the same
// MapFieldBase-derived object, and there is no synchronization going
// on between them, tsan will alert.
#if defined(__SANITIZE_THREAD__) || defined(THREAD_SANITIZER)
void ConstAccess() const { GOOGLE_CHECK_EQ(seq1_, seq2_); }
void MutableAccess() {
if (seq1_ & 1) {
seq2_ = ++seq1_;
} else {
seq1_ = ++seq2_;
}
}
unsigned int seq1_ = 0, seq2_ = 0;
#else
void ConstAccess() const {}
void MutableAccess() {}
#endif
enum State { enum State {
STATE_MODIFIED_MAP = 0, // map has newly added data that has not been STATE_MODIFIED_MAP = 0, // map has newly added data that has not been
// synchronized to repeated field // synchronized to repeated field
@ -468,7 +491,7 @@ class TypeDefinedMapFieldBase : public MapFieldBase {
}; };
// This class provides access to map field using generated api. It is used for // This class provides access to map field using generated api. It is used for
// internal generated message implentation only. Users should never use this // internal generated message implementation only. Users should never use this
// directly. // directly.
template <typename Derived, typename Key, typename T, template <typename Derived, typename Key, typename T,
WireFormatLite::FieldType kKeyFieldType, WireFormatLite::FieldType kKeyFieldType,
@ -504,6 +527,9 @@ class MapField : public TypeDefinedMapFieldBase<Key, T> {
// Implement MapFieldBase // Implement MapFieldBase
bool ContainsMapKey(const MapKey& map_key) const override; bool ContainsMapKey(const MapKey& map_key) const override;
bool InsertOrLookupMapValue(const MapKey& map_key, MapValueRef* val) override; bool InsertOrLookupMapValue(const MapKey& map_key, MapValueRef* val) override;
bool LookupMapValue(const MapKey& map_key,
MapValueConstRef* val) const override;
bool LookupMapValue(const MapKey&, MapValueRef*) const = delete;
bool DeleteMapValue(const MapKey& map_key) override; bool DeleteMapValue(const MapKey& map_key) override;
const Map<Key, T>& GetMap() const override { const Map<Key, T>& GetMap() const override {
@ -597,6 +623,9 @@ class PROTOBUF_EXPORT DynamicMapField
// Implement MapFieldBase // Implement MapFieldBase
bool ContainsMapKey(const MapKey& map_key) const override; bool ContainsMapKey(const MapKey& map_key) const override;
bool InsertOrLookupMapValue(const MapKey& map_key, MapValueRef* val) override; bool InsertOrLookupMapValue(const MapKey& map_key, MapValueRef* val) override;
bool LookupMapValue(const MapKey& map_key,
MapValueConstRef* val) const override;
bool LookupMapValue(const MapKey&, MapValueRef*) const = delete;
bool DeleteMapValue(const MapKey& map_key) override; bool DeleteMapValue(const MapKey& map_key) override;
void MergeFrom(const MapFieldBase& other) override; void MergeFrom(const MapFieldBase& other) override;
void Swap(MapFieldBase* other) override; void Swap(MapFieldBase* other) override;
@ -623,96 +652,76 @@ class PROTOBUF_EXPORT DynamicMapField
} // namespace internal } // namespace internal
// MapValueRef points to a map value. // MapValueConstRef points to a map value. Users can NOT modify
class PROTOBUF_EXPORT MapValueRef { // the map value.
class PROTOBUF_EXPORT MapValueConstRef {
public: public:
MapValueRef() : data_(NULL), type_(0) {} MapValueConstRef() : data_(nullptr), type_(0) {}
void SetInt64Value(int64 value) {
TYPE_CHECK(FieldDescriptor::CPPTYPE_INT64, "MapValueRef::SetInt64Value");
*reinterpret_cast<int64*>(data_) = value;
}
void SetUInt64Value(uint64 value) {
TYPE_CHECK(FieldDescriptor::CPPTYPE_UINT64, "MapValueRef::SetUInt64Value");
*reinterpret_cast<uint64*>(data_) = value;
}
void SetInt32Value(int32 value) {
TYPE_CHECK(FieldDescriptor::CPPTYPE_INT32, "MapValueRef::SetInt32Value");
*reinterpret_cast<int32*>(data_) = value;
}
void SetUInt32Value(uint32 value) {
TYPE_CHECK(FieldDescriptor::CPPTYPE_UINT32, "MapValueRef::SetUInt32Value");
*reinterpret_cast<uint32*>(data_) = value;
}
void SetBoolValue(bool value) {
TYPE_CHECK(FieldDescriptor::CPPTYPE_BOOL, "MapValueRef::SetBoolValue");
*reinterpret_cast<bool*>(data_) = value;
}
// TODO(jieluo) - Checks that enum is member.
void SetEnumValue(int value) {
TYPE_CHECK(FieldDescriptor::CPPTYPE_ENUM, "MapValueRef::SetEnumValue");
*reinterpret_cast<int*>(data_) = value;
}
void SetStringValue(const std::string& value) {
TYPE_CHECK(FieldDescriptor::CPPTYPE_STRING, "MapValueRef::SetStringValue");
*reinterpret_cast<std::string*>(data_) = value;
}
void SetFloatValue(float value) {
TYPE_CHECK(FieldDescriptor::CPPTYPE_FLOAT, "MapValueRef::SetFloatValue");
*reinterpret_cast<float*>(data_) = value;
}
void SetDoubleValue(double value) {
TYPE_CHECK(FieldDescriptor::CPPTYPE_DOUBLE, "MapValueRef::SetDoubleValue");
*reinterpret_cast<double*>(data_) = value;
}
int64 GetInt64Value() const { int64 GetInt64Value() const {
TYPE_CHECK(FieldDescriptor::CPPTYPE_INT64, "MapValueRef::GetInt64Value"); TYPE_CHECK(FieldDescriptor::CPPTYPE_INT64,
"MapValueConstRef::GetInt64Value");
return *reinterpret_cast<int64*>(data_); return *reinterpret_cast<int64*>(data_);
} }
uint64 GetUInt64Value() const { uint64 GetUInt64Value() const {
TYPE_CHECK(FieldDescriptor::CPPTYPE_UINT64, "MapValueRef::GetUInt64Value"); TYPE_CHECK(FieldDescriptor::CPPTYPE_UINT64,
"MapValueConstRef::GetUInt64Value");
return *reinterpret_cast<uint64*>(data_); return *reinterpret_cast<uint64*>(data_);
} }
int32 GetInt32Value() const { int32 GetInt32Value() const {
TYPE_CHECK(FieldDescriptor::CPPTYPE_INT32, "MapValueRef::GetInt32Value"); TYPE_CHECK(FieldDescriptor::CPPTYPE_INT32,
"MapValueConstRef::GetInt32Value");
return *reinterpret_cast<int32*>(data_); return *reinterpret_cast<int32*>(data_);
} }
uint32 GetUInt32Value() const { uint32 GetUInt32Value() const {
TYPE_CHECK(FieldDescriptor::CPPTYPE_UINT32, "MapValueRef::GetUInt32Value"); TYPE_CHECK(FieldDescriptor::CPPTYPE_UINT32,
"MapValueConstRef::GetUInt32Value");
return *reinterpret_cast<uint32*>(data_); return *reinterpret_cast<uint32*>(data_);
} }
bool GetBoolValue() const { bool GetBoolValue() const {
TYPE_CHECK(FieldDescriptor::CPPTYPE_BOOL, "MapValueRef::GetBoolValue"); TYPE_CHECK(FieldDescriptor::CPPTYPE_BOOL, "MapValueConstRef::GetBoolValue");
return *reinterpret_cast<bool*>(data_); return *reinterpret_cast<bool*>(data_);
} }
int GetEnumValue() const { int GetEnumValue() const {
TYPE_CHECK(FieldDescriptor::CPPTYPE_ENUM, "MapValueRef::GetEnumValue"); TYPE_CHECK(FieldDescriptor::CPPTYPE_ENUM, "MapValueConstRef::GetEnumValue");
return *reinterpret_cast<int*>(data_); return *reinterpret_cast<int*>(data_);
} }
const std::string& GetStringValue() const { const std::string& GetStringValue() const {
TYPE_CHECK(FieldDescriptor::CPPTYPE_STRING, "MapValueRef::GetStringValue"); TYPE_CHECK(FieldDescriptor::CPPTYPE_STRING,
"MapValueConstRef::GetStringValue");
return *reinterpret_cast<std::string*>(data_); return *reinterpret_cast<std::string*>(data_);
} }
float GetFloatValue() const { float GetFloatValue() const {
TYPE_CHECK(FieldDescriptor::CPPTYPE_FLOAT, "MapValueRef::GetFloatValue"); TYPE_CHECK(FieldDescriptor::CPPTYPE_FLOAT,
"MapValueConstRef::GetFloatValue");
return *reinterpret_cast<float*>(data_); return *reinterpret_cast<float*>(data_);
} }
double GetDoubleValue() const { double GetDoubleValue() const {
TYPE_CHECK(FieldDescriptor::CPPTYPE_DOUBLE, "MapValueRef::GetDoubleValue"); TYPE_CHECK(FieldDescriptor::CPPTYPE_DOUBLE,
"MapValueConstRef::GetDoubleValue");
return *reinterpret_cast<double*>(data_); return *reinterpret_cast<double*>(data_);
} }
const Message& GetMessageValue() const { const Message& GetMessageValue() const {
TYPE_CHECK(FieldDescriptor::CPPTYPE_MESSAGE, TYPE_CHECK(FieldDescriptor::CPPTYPE_MESSAGE,
"MapValueRef::GetMessageValue"); "MapValueConstRef::GetMessageValue");
return *reinterpret_cast<Message*>(data_); return *reinterpret_cast<Message*>(data_);
} }
Message* MutableMessageValue() { protected:
TYPE_CHECK(FieldDescriptor::CPPTYPE_MESSAGE, // data_ point to a map value. MapValueConstRef does not
"MapValueRef::MutableMessageValue"); // own this value.
return reinterpret_cast<Message*>(data_); void* data_;
// type_ is 0 or a valid FieldDescriptor::CppType.
int type_;
FieldDescriptor::CppType type() const {
if (type_ == 0 || data_ == nullptr) {
GOOGLE_LOG(FATAL)
<< "Protocol Buffer map usage error:\n"
<< "MapValueConstRef::type MapValueConstRef is not initialized.";
}
return static_cast<FieldDescriptor::CppType>(type_);
} }
private: private:
@ -727,19 +736,66 @@ class PROTOBUF_EXPORT MapValueRef {
friend class internal::DynamicMapField; friend class internal::DynamicMapField;
void SetType(FieldDescriptor::CppType type) { type_ = type; } void SetType(FieldDescriptor::CppType type) { type_ = type; }
FieldDescriptor::CppType type() const {
if (type_ == 0 || data_ == NULL) {
GOOGLE_LOG(FATAL) << "Protocol Buffer map usage error:\n"
<< "MapValueRef::type MapValueRef is not initialized.";
}
return (FieldDescriptor::CppType)type_;
}
void SetValue(const void* val) { data_ = const_cast<void*>(val); } void SetValue(const void* val) { data_ = const_cast<void*>(val); }
void CopyFrom(const MapValueRef& other) { void CopyFrom(const MapValueConstRef& other) {
type_ = other.type_; type_ = other.type_;
data_ = other.data_; data_ = other.data_;
} }
};
// MapValueRef points to a map value. Users are able to modify
// the map value.
class PROTOBUF_EXPORT MapValueRef final : public MapValueConstRef {
public:
MapValueRef() {}
void SetInt64Value(int64 value) {
TYPE_CHECK(FieldDescriptor::CPPTYPE_INT64, "MapValueRef::SetInt64Value");
*reinterpret_cast<int64*>(data_) = value;
}
void SetUInt64Value(uint64 value) {
TYPE_CHECK(FieldDescriptor::CPPTYPE_UINT64, "MapValueRef::SetUInt64Value");
*reinterpret_cast<uint64*>(data_) = value;
}
void SetInt32Value(int32 value) {
TYPE_CHECK(FieldDescriptor::CPPTYPE_INT32, "MapValueRef::SetInt32Value");
*reinterpret_cast<int32*>(data_) = value;
}
void SetUInt32Value(uint32 value) {
TYPE_CHECK(FieldDescriptor::CPPTYPE_UINT32, "MapValueRef::SetUInt32Value");
*reinterpret_cast<uint32*>(data_) = value;
}
void SetBoolValue(bool value) {
TYPE_CHECK(FieldDescriptor::CPPTYPE_BOOL, "MapValueRef::SetBoolValue");
*reinterpret_cast<bool*>(data_) = value;
}
// TODO(jieluo) - Checks that enum is member.
void SetEnumValue(int value) {
TYPE_CHECK(FieldDescriptor::CPPTYPE_ENUM, "MapValueRef::SetEnumValue");
*reinterpret_cast<int*>(data_) = value;
}
void SetStringValue(const std::string& value) {
TYPE_CHECK(FieldDescriptor::CPPTYPE_STRING, "MapValueRef::SetStringValue");
*reinterpret_cast<std::string*>(data_) = value;
}
void SetFloatValue(float value) {
TYPE_CHECK(FieldDescriptor::CPPTYPE_FLOAT, "MapValueRef::SetFloatValue");
*reinterpret_cast<float*>(data_) = value;
}
void SetDoubleValue(double value) {
TYPE_CHECK(FieldDescriptor::CPPTYPE_DOUBLE, "MapValueRef::SetDoubleValue");
*reinterpret_cast<double*>(data_) = value;
}
Message* MutableMessageValue() {
TYPE_CHECK(FieldDescriptor::CPPTYPE_MESSAGE,
"MapValueRef::MutableMessageValue");
return reinterpret_cast<Message*>(data_);
}
private:
friend class internal::DynamicMapField;
// Only used in DynamicMapField // Only used in DynamicMapField
void DeleteData() { void DeleteData() {
switch (type_) { switch (type_) {
@ -761,11 +817,6 @@ class PROTOBUF_EXPORT MapValueRef {
#undef HANDLE_TYPE #undef HANDLE_TYPE
} }
} }
// data_ point to a map value. MapValueRef does not
// own this value.
void* data_;
// type_ is 0 or a valid FieldDescriptor::CppType.
int type_;
}; };
#undef TYPE_CHECK #undef TYPE_CHECK

@ -234,6 +234,23 @@ bool MapField<Derived, Key, T, kKeyFieldType,
return false; return false;
} }
template <typename Derived, typename Key, typename T,
WireFormatLite::FieldType kKeyFieldType,
WireFormatLite::FieldType kValueFieldType>
bool MapField<Derived, Key, T, kKeyFieldType, kValueFieldType>::LookupMapValue(
const MapKey& map_key, MapValueConstRef* val) const {
const Map<Key, T>& map = GetMap();
const Key& key = UnwrapMapKey<Key>(map_key);
typename Map<Key, T>::const_iterator iter = map.find(key);
if (map.end() == iter) {
return false;
}
// Key is already in the map. Make sure (*map)[key] is not called.
// [] may reorder the map and iterators.
val->SetValue(&(iter->second));
return true;
}
template <typename Derived, typename Key, typename T, template <typename Derived, typename Key, typename T,
WireFormatLite::FieldType kKeyFieldType, WireFormatLite::FieldType kKeyFieldType,
WireFormatLite::FieldType kValueFieldType> WireFormatLite::FieldType kValueFieldType>

@ -50,7 +50,7 @@ namespace protobuf {
namespace internal { namespace internal {
// This class provides access to map field using generated api. It is used for // This class provides access to map field using generated api. It is used for
// internal generated message implentation only. Users should never use this // internal generated message implementation only. Users should never use this
// directly. // directly.
template <typename Derived, typename Key, typename T, template <typename Derived, typename Key, typename T,
WireFormatLite::FieldType key_wire_type, WireFormatLite::FieldType key_wire_type,

@ -77,6 +77,10 @@ class MapFieldBaseStub : public MapFieldBase {
MapValueRef* val) override { MapValueRef* val) override {
return false; return false;
} }
bool LookupMapValue(const MapKey& map_key,
MapValueConstRef* val) const override {
return false;
}
bool DeleteMapValue(const MapKey& map_key) override { return false; } bool DeleteMapValue(const MapKey& map_key) override { return false; }
bool EqualIterator(const MapIterator& a, bool EqualIterator(const MapIterator& a,
const MapIterator& b) const override { const MapIterator& b) const override {

@ -234,9 +234,10 @@ TEST_F(MapImplTest, UsageErrors) {
" Actual : int64"); " Actual : int64");
MapValueRef value; MapValueRef value;
EXPECT_DEATH(value.SetFloatValue(0.1), EXPECT_DEATH(
"Protocol Buffer map usage error:\n" value.SetFloatValue(0.1),
"MapValueRef::type MapValueRef is not initialized."); "Protocol Buffer map usage error:\n"
"MapValue[Const]*Ref::type MapValue[Const]*Ref is not initialized.");
} }
#endif // PROTOBUF_HAS_DEATH_TEST #endif // PROTOBUF_HAS_DEATH_TEST
@ -3216,9 +3217,9 @@ TEST(WireFormatForMapFieldTest, MapByteSizeDynamicMessage) {
// Protobuf used to have a bug for serialize when map it marked CLEAN. It used // Protobuf used to have a bug for serialize when map it marked CLEAN. It used
// repeated field to calculate ByteSizeLong but use map to serialize the real // repeated field to calculate ByteSizeLong but use map to serialize the real
// data, thus the ByteSizeLong may bigger than real serialized size. A crash // data, thus the ByteSizeLong may bigger than real serialized size. A crash
// might be happen at SerializeToString(). Or an "unexpect end group" warning // might be happen at SerializeToString(). Or an "unexpected end group"
// was raised at parse back if user use SerializeWithCachedSizes() which // warning was raised at parse back if user use SerializeWithCachedSizes()
// avoids size check at serialize. // which avoids size check at serialize.
std::string serialized_data; std::string serialized_data;
dynamic_message->SerializeToString(&serialized_data); dynamic_message->SerializeToString(&serialized_data);
EXPECT_EQ(serialized_data, expected_serialized_data); EXPECT_EQ(serialized_data, expected_serialized_data);

@ -495,20 +495,27 @@ inline void MapReflectionTester::SetMapFieldsViaMapReflection(
Message* sub_foreign_message = nullptr; Message* sub_foreign_message = nullptr;
MapValueRef map_val; MapValueRef map_val;
MapValueConstRef map_val_const;
// Add first element. // Add first element.
MapKey map_key; MapKey map_key;
map_key.SetInt32Value(0); map_key.SetInt32Value(0);
EXPECT_FALSE(reflection->LookupMapValue(*message, F("map_int32_int32"),
map_key, &map_val_const));
EXPECT_TRUE(reflection->InsertOrLookupMapValue(message, F("map_int32_int32"), EXPECT_TRUE(reflection->InsertOrLookupMapValue(message, F("map_int32_int32"),
map_key, &map_val)); map_key, &map_val));
map_val.SetInt32Value(0); map_val.SetInt32Value(0);
map_key.SetInt64Value(0); map_key.SetInt64Value(0);
EXPECT_FALSE(reflection->LookupMapValue(*message, F("map_int64_int64"),
map_key, &map_val_const));
EXPECT_TRUE(reflection->InsertOrLookupMapValue(message, F("map_int64_int64"), EXPECT_TRUE(reflection->InsertOrLookupMapValue(message, F("map_int64_int64"),
map_key, &map_val)); map_key, &map_val));
map_val.SetInt64Value(0); map_val.SetInt64Value(0);
map_key.SetUInt32Value(0); map_key.SetUInt32Value(0);
EXPECT_FALSE(reflection->LookupMapValue(*message, F("map_uint32_uint32"),
map_key, &map_val_const));
EXPECT_TRUE(reflection->InsertOrLookupMapValue( EXPECT_TRUE(reflection->InsertOrLookupMapValue(
message, F("map_uint32_uint32"), map_key, &map_val)); message, F("map_uint32_uint32"), map_key, &map_val));
map_val.SetUInt32Value(0); map_val.SetUInt32Value(0);
@ -559,26 +566,36 @@ inline void MapReflectionTester::SetMapFieldsViaMapReflection(
map_val.SetDoubleValue(0.0); map_val.SetDoubleValue(0.0);
map_key.SetBoolValue(false); map_key.SetBoolValue(false);
EXPECT_FALSE(reflection->LookupMapValue(*message, F("map_bool_bool"), map_key,
&map_val_const));
EXPECT_TRUE(reflection->InsertOrLookupMapValue(message, F("map_bool_bool"), EXPECT_TRUE(reflection->InsertOrLookupMapValue(message, F("map_bool_bool"),
map_key, &map_val)); map_key, &map_val));
map_val.SetBoolValue(false); map_val.SetBoolValue(false);
map_key.SetStringValue("0"); map_key.SetStringValue("0");
EXPECT_FALSE(reflection->LookupMapValue(*message, F("map_string_string"),
map_key, &map_val_const));
EXPECT_TRUE(reflection->InsertOrLookupMapValue( EXPECT_TRUE(reflection->InsertOrLookupMapValue(
message, F("map_string_string"), map_key, &map_val)); message, F("map_string_string"), map_key, &map_val));
map_val.SetStringValue("0"); map_val.SetStringValue("0");
map_key.SetInt32Value(0); map_key.SetInt32Value(0);
EXPECT_FALSE(reflection->LookupMapValue(*message, F("map_int32_bytes"),
map_key, &map_val_const));
EXPECT_TRUE(reflection->InsertOrLookupMapValue(message, F("map_int32_bytes"), EXPECT_TRUE(reflection->InsertOrLookupMapValue(message, F("map_int32_bytes"),
map_key, &map_val)); map_key, &map_val));
map_val.SetStringValue("0"); map_val.SetStringValue("0");
map_key.SetInt32Value(0); map_key.SetInt32Value(0);
EXPECT_FALSE(reflection->LookupMapValue(*message, F("map_int32_enum"),
map_key, &map_val_const));
EXPECT_TRUE(reflection->InsertOrLookupMapValue(message, F("map_int32_enum"), EXPECT_TRUE(reflection->InsertOrLookupMapValue(message, F("map_int32_enum"),
map_key, &map_val)); map_key, &map_val));
map_val.SetEnumValue(map_enum_bar_->number()); map_val.SetEnumValue(map_enum_bar_->number());
map_key.SetInt32Value(0); map_key.SetInt32Value(0);
EXPECT_FALSE(reflection->LookupMapValue(
*message, F("map_int32_foreign_message"), map_key, &map_val_const));
EXPECT_TRUE(reflection->InsertOrLookupMapValue( EXPECT_TRUE(reflection->InsertOrLookupMapValue(
message, F("map_int32_foreign_message"), map_key, &map_val)); message, F("map_int32_foreign_message"), map_key, &map_val));
sub_foreign_message = map_val.MutableMessageValue(); sub_foreign_message = map_val.MutableMessageValue();
@ -933,6 +950,7 @@ inline void MapReflectionTester::ExpectMapFieldsSetViaReflection(
const Reflection* reflection = message.GetReflection(); const Reflection* reflection = message.GetReflection();
const Message* sub_message; const Message* sub_message;
MapKey map_key; MapKey map_key;
MapValueConstRef map_value_const_ref;
// ----------------------------------------------------------------- // -----------------------------------------------------------------
@ -971,6 +989,9 @@ inline void MapReflectionTester::ExpectMapFieldsSetViaReflection(
map_key.SetInt32Value(key); map_key.SetInt32Value(key);
EXPECT_TRUE( EXPECT_TRUE(
reflection->ContainsMapKey(message, F("map_int32_int32"), map_key)); reflection->ContainsMapKey(message, F("map_int32_int32"), map_key));
EXPECT_TRUE(reflection->LookupMapValue(message, F("map_int32_int32"),
map_key, &map_value_const_ref));
EXPECT_EQ(map_value_const_ref.GetInt32Value(), val);
} }
} }
{ {
@ -990,6 +1011,9 @@ inline void MapReflectionTester::ExpectMapFieldsSetViaReflection(
map_key.SetInt64Value(key); map_key.SetInt64Value(key);
EXPECT_TRUE( EXPECT_TRUE(
reflection->ContainsMapKey(message, F("map_int64_int64"), map_key)); reflection->ContainsMapKey(message, F("map_int64_int64"), map_key));
EXPECT_TRUE(reflection->LookupMapValue(message, F("map_int64_int64"),
map_key, &map_value_const_ref));
EXPECT_EQ(map_value_const_ref.GetInt64Value(), val);
} }
} }
{ {
@ -1009,6 +1033,9 @@ inline void MapReflectionTester::ExpectMapFieldsSetViaReflection(
map_key.SetUInt32Value(key); map_key.SetUInt32Value(key);
EXPECT_TRUE( EXPECT_TRUE(
reflection->ContainsMapKey(message, F("map_uint32_uint32"), map_key)); reflection->ContainsMapKey(message, F("map_uint32_uint32"), map_key));
EXPECT_TRUE(reflection->LookupMapValue(message, F("map_uint32_uint32"),
map_key, &map_value_const_ref));
EXPECT_EQ(map_value_const_ref.GetUInt32Value(), val);
} }
} }
{ {
@ -1027,6 +1054,9 @@ inline void MapReflectionTester::ExpectMapFieldsSetViaReflection(
map_key.SetUInt64Value(key); map_key.SetUInt64Value(key);
EXPECT_TRUE( EXPECT_TRUE(
reflection->ContainsMapKey(message, F("map_uint64_uint64"), map_key)); reflection->ContainsMapKey(message, F("map_uint64_uint64"), map_key));
EXPECT_TRUE(reflection->LookupMapValue(message, F("map_uint64_uint64"),
map_key, &map_value_const_ref));
EXPECT_EQ(map_value_const_ref.GetUInt64Value(), val);
} }
} }
{ {
@ -1045,6 +1075,9 @@ inline void MapReflectionTester::ExpectMapFieldsSetViaReflection(
map_key.SetInt32Value(key); map_key.SetInt32Value(key);
EXPECT_EQ(true, reflection->ContainsMapKey( EXPECT_EQ(true, reflection->ContainsMapKey(
message, F("map_sint32_sint32"), map_key)); message, F("map_sint32_sint32"), map_key));
EXPECT_TRUE(reflection->LookupMapValue(message, F("map_sint32_sint32"),
map_key, &map_value_const_ref));
EXPECT_EQ(map_value_const_ref.GetInt32Value(), val);
} }
} }
{ {
@ -1063,6 +1096,9 @@ inline void MapReflectionTester::ExpectMapFieldsSetViaReflection(
map_key.SetInt64Value(key); map_key.SetInt64Value(key);
EXPECT_EQ(true, reflection->ContainsMapKey( EXPECT_EQ(true, reflection->ContainsMapKey(
message, F("map_sint64_sint64"), map_key)); message, F("map_sint64_sint64"), map_key));
EXPECT_TRUE(reflection->LookupMapValue(message, F("map_sint64_sint64"),
map_key, &map_value_const_ref));
EXPECT_EQ(map_value_const_ref.GetInt64Value(), val);
} }
} }
{ {
@ -1081,6 +1117,9 @@ inline void MapReflectionTester::ExpectMapFieldsSetViaReflection(
map_key.SetUInt32Value(key); map_key.SetUInt32Value(key);
EXPECT_EQ(true, reflection->ContainsMapKey( EXPECT_EQ(true, reflection->ContainsMapKey(
message, F("map_fixed32_fixed32"), map_key)); message, F("map_fixed32_fixed32"), map_key));
EXPECT_TRUE(reflection->LookupMapValue(message, F("map_fixed32_fixed32"),
map_key, &map_value_const_ref));
EXPECT_EQ(map_value_const_ref.GetUInt32Value(), val);
} }
} }
{ {
@ -1099,6 +1138,9 @@ inline void MapReflectionTester::ExpectMapFieldsSetViaReflection(
map_key.SetUInt64Value(key); map_key.SetUInt64Value(key);
EXPECT_EQ(true, reflection->ContainsMapKey( EXPECT_EQ(true, reflection->ContainsMapKey(
message, F("map_fixed64_fixed64"), map_key)); message, F("map_fixed64_fixed64"), map_key));
EXPECT_TRUE(reflection->LookupMapValue(message, F("map_fixed64_fixed64"),
map_key, &map_value_const_ref));
EXPECT_EQ(map_value_const_ref.GetUInt64Value(), val);
} }
} }
{ {
@ -1117,6 +1159,9 @@ inline void MapReflectionTester::ExpectMapFieldsSetViaReflection(
map_key.SetInt32Value(key); map_key.SetInt32Value(key);
EXPECT_EQ(true, reflection->ContainsMapKey( EXPECT_EQ(true, reflection->ContainsMapKey(
message, F("map_sfixed32_sfixed32"), map_key)); message, F("map_sfixed32_sfixed32"), map_key));
EXPECT_TRUE(reflection->LookupMapValue(
message, F("map_sfixed32_sfixed32"), map_key, &map_value_const_ref));
EXPECT_EQ(map_value_const_ref.GetInt32Value(), val);
} }
} }
{ {
@ -1135,6 +1180,9 @@ inline void MapReflectionTester::ExpectMapFieldsSetViaReflection(
map_key.SetInt64Value(key); map_key.SetInt64Value(key);
EXPECT_EQ(true, reflection->ContainsMapKey( EXPECT_EQ(true, reflection->ContainsMapKey(
message, F("map_sfixed64_sfixed64"), map_key)); message, F("map_sfixed64_sfixed64"), map_key));
EXPECT_TRUE(reflection->LookupMapValue(
message, F("map_sfixed64_sfixed64"), map_key, &map_value_const_ref));
EXPECT_EQ(map_value_const_ref.GetInt64Value(), val);
} }
} }
{ {
@ -1153,6 +1201,9 @@ inline void MapReflectionTester::ExpectMapFieldsSetViaReflection(
map_key.SetInt32Value(key); map_key.SetInt32Value(key);
EXPECT_EQ(true, reflection->ContainsMapKey(message, F("map_int32_float"), EXPECT_EQ(true, reflection->ContainsMapKey(message, F("map_int32_float"),
map_key)); map_key));
EXPECT_TRUE(reflection->LookupMapValue(message, F("map_int32_float"),
map_key, &map_value_const_ref));
EXPECT_EQ(map_value_const_ref.GetFloatValue(), val);
} }
} }
{ {
@ -1171,6 +1222,9 @@ inline void MapReflectionTester::ExpectMapFieldsSetViaReflection(
map_key.SetInt32Value(key); map_key.SetInt32Value(key);
EXPECT_EQ(true, reflection->ContainsMapKey(message, F("map_int32_double"), EXPECT_EQ(true, reflection->ContainsMapKey(message, F("map_int32_double"),
map_key)); map_key));
EXPECT_TRUE(reflection->LookupMapValue(message, F("map_int32_double"),
map_key, &map_value_const_ref));
EXPECT_EQ(map_value_const_ref.GetDoubleValue(), val);
} }
} }
{ {
@ -1189,6 +1243,9 @@ inline void MapReflectionTester::ExpectMapFieldsSetViaReflection(
map_key.SetBoolValue(key); map_key.SetBoolValue(key);
EXPECT_EQ(true, reflection->ContainsMapKey(message, F("map_bool_bool"), EXPECT_EQ(true, reflection->ContainsMapKey(message, F("map_bool_bool"),
map_key)); map_key));
EXPECT_TRUE(reflection->LookupMapValue(message, F("map_bool_bool"),
map_key, &map_value_const_ref));
EXPECT_EQ(map_value_const_ref.GetBoolValue(), val);
} }
} }
{ {
@ -1207,6 +1264,9 @@ inline void MapReflectionTester::ExpectMapFieldsSetViaReflection(
map_key.SetStringValue(key); map_key.SetStringValue(key);
EXPECT_EQ(true, reflection->ContainsMapKey( EXPECT_EQ(true, reflection->ContainsMapKey(
message, F("map_string_string"), map_key)); message, F("map_string_string"), map_key));
EXPECT_TRUE(reflection->LookupMapValue(message, F("map_string_string"),
map_key, &map_value_const_ref));
EXPECT_EQ(map_value_const_ref.GetStringValue(), val);
} }
} }
{ {
@ -1225,6 +1285,9 @@ inline void MapReflectionTester::ExpectMapFieldsSetViaReflection(
map_key.SetInt32Value(key); map_key.SetInt32Value(key);
EXPECT_EQ(true, reflection->ContainsMapKey(message, F("map_int32_bytes"), EXPECT_EQ(true, reflection->ContainsMapKey(message, F("map_int32_bytes"),
map_key)); map_key));
EXPECT_TRUE(reflection->LookupMapValue(message, F("map_int32_bytes"),
map_key, &map_value_const_ref));
EXPECT_EQ(map_value_const_ref.GetStringValue(), val);
} }
} }
{ {
@ -1243,6 +1306,9 @@ inline void MapReflectionTester::ExpectMapFieldsSetViaReflection(
map_key.SetInt32Value(key); map_key.SetInt32Value(key);
EXPECT_EQ(true, reflection->ContainsMapKey(message, F("map_int32_enum"), EXPECT_EQ(true, reflection->ContainsMapKey(message, F("map_int32_enum"),
map_key)); map_key));
EXPECT_TRUE(reflection->LookupMapValue(message, F("map_int32_enum"),
map_key, &map_value_const_ref));
EXPECT_EQ(map_value_const_ref.GetEnumValue(), val->number());
} }
} }
{ {
@ -1263,6 +1329,12 @@ inline void MapReflectionTester::ExpectMapFieldsSetViaReflection(
map_key.SetInt32Value(key); map_key.SetInt32Value(key);
EXPECT_EQ(true, reflection->ContainsMapKey( EXPECT_EQ(true, reflection->ContainsMapKey(
message, F("map_int32_foreign_message"), map_key)); message, F("map_int32_foreign_message"), map_key));
EXPECT_TRUE(reflection->LookupMapValue(message,
F("map_int32_foreign_message"),
map_key, &map_value_const_ref));
EXPECT_EQ(foreign_message.GetReflection()->GetInt32(
map_value_const_ref.GetMessageValue(), foreign_c_),
val);
} }
} }
} }

@ -145,6 +145,7 @@ class MessageFactory;
class AssignDescriptorsHelper; class AssignDescriptorsHelper;
class DynamicMessageFactory; class DynamicMessageFactory;
class MapKey; class MapKey;
class MapValueConstRef;
class MapValueRef; class MapValueRef;
class MapIterator; class MapIterator;
class MapReflectionTester; class MapReflectionTester;
@ -758,7 +759,7 @@ class PROTOBUF_EXPORT Reflection final {
Message* message, const FieldDescriptor* field) const; Message* message, const FieldDescriptor* field) const;
// DEPRECATED. Please use Get(Mutable)RepeatedFieldRef() for repeated field // DEPRECATED. Please use Get(Mutable)RepeatedFieldRef() for repeated field
// access. The following repeated field accesors will be removed in the // access. The following repeated field accessors will be removed in the
// future. // future.
// //
// Repeated field accessors ------------------------------------------------- // Repeated field accessors -------------------------------------------------
@ -981,10 +982,19 @@ class PROTOBUF_EXPORT Reflection final {
// If key is in map field: Saves the value pointer to val and returns // If key is in map field: Saves the value pointer to val and returns
// false. If key in not in map field: Insert the key into map, saves // false. If key in not in map field: Insert the key into map, saves
// value pointer to val and returns true. // value pointer to val and returns true. Users are able to modify the
// map value by MapValueRef.
bool InsertOrLookupMapValue(Message* message, const FieldDescriptor* field, bool InsertOrLookupMapValue(Message* message, const FieldDescriptor* field,
const MapKey& key, MapValueRef* val) const; const MapKey& key, MapValueRef* val) const;
// If key is in map field: Saves the value pointer to val and returns true.
// Returns false if key is not in map field. Users are NOT able to modify
// the value by MapValueConstRef.
bool LookupMapValue(const Message& message, const FieldDescriptor* field,
const MapKey& key, MapValueConstRef* val) const;
bool LookupMapValue(const Message&, const FieldDescriptor*, const MapKey&,
MapValueRef*) const = delete;
// Delete and returns true if key is in the map field. Returns false // Delete and returns true if key is in the map field. Returns false
// otherwise. // otherwise.
bool DeleteMapValue(Message* message, const FieldDescriptor* field, bool DeleteMapValue(Message* message, const FieldDescriptor* field,

@ -180,7 +180,7 @@ std::pair<const char*, bool> EpsCopyInputStream::DoneFallback(const char* ptr,
if (PROTOBUF_PREDICT_FALSE(overrun != 0)) return {nullptr, true}; if (PROTOBUF_PREDICT_FALSE(overrun != 0)) return {nullptr, true};
GOOGLE_DCHECK(limit_ > 0); GOOGLE_DCHECK(limit_ > 0);
limit_end_ = buffer_end_; limit_end_ = buffer_end_;
// Distinquish ending on a pushed limit or ending on end-of-stream. // Distinguish ending on a pushed limit or ending on end-of-stream.
SetEndOfStream(); SetEndOfStream();
return {ptr, true}; return {ptr, true};
} }

@ -300,14 +300,14 @@
// Shared google3/opensource definitions. ////////////////////////////////////// // Shared google3/opensource definitions. //////////////////////////////////////
#define PROTOBUF_VERSION 3012003 #define PROTOBUF_VERSION 3013000
#define PROTOBUF_MIN_HEADER_VERSION_FOR_PROTOC 3012000 #define PROTOBUF_MIN_HEADER_VERSION_FOR_PROTOC 3013000
#define PROTOBUF_MIN_PROTOC_VERSION 3012000 #define PROTOBUF_MIN_PROTOC_VERSION 3013000
#define PROTOBUF_VERSION_SUFFIX "" #define PROTOBUF_VERSION_SUFFIX ""
// The minimum library version which works with the current version of the // The minimum library version which works with the current version of the
// headers. // headers.
#define GOOGLE_PROTOBUF_MIN_LIBRARY_VERSION 3012000 #define GOOGLE_PROTOBUF_MIN_LIBRARY_VERSION 3013000
#if defined(GOOGLE_PROTOBUF_NO_RTTI) && GOOGLE_PROTOBUF_NO_RTTI #if defined(GOOGLE_PROTOBUF_NO_RTTI) && GOOGLE_PROTOBUF_NO_RTTI
#define PROTOBUF_RTTI 0 #define PROTOBUF_RTTI 0

@ -8,12 +8,12 @@
#include <string> #include <string>
#include <google/protobuf/port_def.inc> #include <google/protobuf/port_def.inc>
#if PROTOBUF_VERSION < 3012000 #if PROTOBUF_VERSION < 3013000
#error This file was generated by a newer version of protoc which is #error This file was generated by a newer version of protoc which is
#error incompatible with your Protocol Buffer headers. Please update #error incompatible with your Protocol Buffer headers. Please update
#error your headers. #error your headers.
#endif #endif
#if 3012003 < PROTOBUF_MIN_PROTOC_VERSION #if 3013000 < PROTOBUF_MIN_PROTOC_VERSION
#error This file was generated by an older version of protoc which is #error This file was generated by an older version of protoc which is
#error incompatible with your Protocol Buffer headers. Please #error incompatible with your Protocol Buffer headers. Please
#error regenerate this file with a newer version of protoc. #error regenerate this file with a newer version of protoc.

@ -8,12 +8,12 @@
#include <string> #include <string>
#include <google/protobuf/port_def.inc> #include <google/protobuf/port_def.inc>
#if PROTOBUF_VERSION < 3012000 #if PROTOBUF_VERSION < 3013000
#error This file was generated by a newer version of protoc which is #error This file was generated by a newer version of protoc which is
#error incompatible with your Protocol Buffer headers. Please update #error incompatible with your Protocol Buffer headers. Please update
#error your headers. #error your headers.
#endif #endif
#if 3012003 < PROTOBUF_MIN_PROTOC_VERSION #if 3013000 < PROTOBUF_MIN_PROTOC_VERSION
#error This file was generated by an older version of protoc which is #error This file was generated by an older version of protoc which is
#error incompatible with your Protocol Buffer headers. Please #error incompatible with your Protocol Buffer headers. Please
#error regenerate this file with a newer version of protoc. #error regenerate this file with a newer version of protoc.

@ -47,7 +47,7 @@ namespace internal {
// When you use implicit_cast, the compiler checks that the cast is safe. // When you use implicit_cast, the compiler checks that the cast is safe.
// Such explicit implicit_casts are necessary in surprisingly many // Such explicit implicit_casts are necessary in surprisingly many
// situations where C++ demands an exact type match instead of an // situations where C++ demands an exact type match instead of an
// argument type convertable to a target type. // argument type convertible to a target type.
// //
// The From type can be inferred, so the preferred syntax for using // The From type can be inferred, so the preferred syntax for using
// implicit_cast is the same as for static_cast etc.: // implicit_cast is the same as for static_cast etc.:

@ -304,7 +304,7 @@ void DoNothing() {}
// //
// TODO(xiaofeng): PROTOBUF_LITTLE_ENDIAN is unfortunately defined in // TODO(xiaofeng): PROTOBUF_LITTLE_ENDIAN is unfortunately defined in
// google/protobuf/io/coded_stream.h and therefore can not be used here. // google/protobuf/io/coded_stream.h and therefore can not be used here.
// Maybe move that macro definition here in the furture. // Maybe move that macro definition here in the future.
uint32 ghtonl(uint32 x) { uint32 ghtonl(uint32 x) {
union { union {
uint32 result; uint32 result;

@ -82,7 +82,7 @@ namespace internal {
// The current version, represented as a single integer to make comparison // The current version, represented as a single integer to make comparison
// easier: major * 10^6 + minor * 10^3 + micro // easier: major * 10^6 + minor * 10^3 + micro
#define GOOGLE_PROTOBUF_VERSION 3012003 #define GOOGLE_PROTOBUF_VERSION 3013000
// A suffix string for alpha, beta or rc releases. Empty for stable releases. // A suffix string for alpha, beta or rc releases. Empty for stable releases.
#define GOOGLE_PROTOBUF_VERSION_SUFFIX "" #define GOOGLE_PROTOBUF_VERSION_SUFFIX ""
@ -90,15 +90,15 @@ namespace internal {
// The minimum header version which works with the current version of // The minimum header version which works with the current version of
// the library. This constant should only be used by protoc's C++ code // the library. This constant should only be used by protoc's C++ code
// generator. // generator.
static const int kMinHeaderVersionForLibrary = 3012000; static const int kMinHeaderVersionForLibrary = 3013000;
// The minimum protoc version which works with the current version of the // The minimum protoc version which works with the current version of the
// headers. // headers.
#define GOOGLE_PROTOBUF_MIN_PROTOC_VERSION 3012000 #define GOOGLE_PROTOBUF_MIN_PROTOC_VERSION 3013000
// The minimum header version which works with the current version of // The minimum header version which works with the current version of
// protoc. This constant should only be used in VerifyVersion(). // protoc. This constant should only be used in VerifyVersion().
static const int kMinHeaderVersionForProtoc = 3012000; static const int kMinHeaderVersionForProtoc = 3013000;
// Verifies that the headers and libraries are compatible. Use the macro // Verifies that the headers and libraries are compatible. Use the macro
// below to call this. // below to call this.

@ -38,7 +38,7 @@ namespace internal {
namespace { namespace {
static const int64 kSecondsPerDay = 3600 * 24; static const int64 kSecondsPerDay = 3600 * 24;
// For DateTime, tests will mostly focuse on the date part because that's // For DateTime, tests will mostly focus on the date part because that's
// the tricky one. // the tricky one.
int64 CreateTimestamp(int year, int month, int day) { int64 CreateTimestamp(int year, int month, int day) {
DateTime time; DateTime time;

@ -718,7 +718,7 @@ TEST_F(TextFormatTest, CompactRepeatedFieldPrinter) {
text); text);
} }
// Print strings into multiple line, with indention. Use this to test // Print strings into multiple line, with indentation. Use this to test
// BaseTextGenerator::Indent and BaseTextGenerator::Outdent. // BaseTextGenerator::Indent and BaseTextGenerator::Outdent.
class MultilineStringPrinter : public TextFormat::FastFieldValuePrinter { class MultilineStringPrinter : public TextFormat::FastFieldValuePrinter {
public: public:
@ -2055,7 +2055,7 @@ TEST(TextFormatUnknownFieldTest, TestUnknownField) {
" }\n" " }\n"
">", ">",
&proto)); &proto));
// Unmatched delimeters for message body // Unmatched delimiters for message body
EXPECT_FALSE(parser.ParseFromString("unknown_message: {>", &proto)); EXPECT_FALSE(parser.ParseFromString("unknown_message: {>", &proto));
// Unknown extension // Unknown extension
EXPECT_TRUE( EXPECT_TRUE(

@ -8,12 +8,12 @@
#include <string> #include <string>
#include <google/protobuf/port_def.inc> #include <google/protobuf/port_def.inc>
#if PROTOBUF_VERSION < 3012000 #if PROTOBUF_VERSION < 3013000
#error This file was generated by a newer version of protoc which is #error This file was generated by a newer version of protoc which is
#error incompatible with your Protocol Buffer headers. Please update #error incompatible with your Protocol Buffer headers. Please update
#error your headers. #error your headers.
#endif #endif
#if 3012003 < PROTOBUF_MIN_PROTOC_VERSION #if 3013000 < PROTOBUF_MIN_PROTOC_VERSION
#error This file was generated by an older version of protoc which is #error This file was generated by an older version of protoc which is
#error incompatible with your Protocol Buffer headers. Please #error incompatible with your Protocol Buffer headers. Please
#error regenerate this file with a newer version of protoc. #error regenerate this file with a newer version of protoc.

@ -8,12 +8,12 @@
#include <string> #include <string>
#include <google/protobuf/port_def.inc> #include <google/protobuf/port_def.inc>
#if PROTOBUF_VERSION < 3012000 #if PROTOBUF_VERSION < 3013000
#error This file was generated by a newer version of protoc which is #error This file was generated by a newer version of protoc which is
#error incompatible with your Protocol Buffer headers. Please update #error incompatible with your Protocol Buffer headers. Please update
#error your headers. #error your headers.
#endif #endif
#if 3012003 < PROTOBUF_MIN_PROTOC_VERSION #if 3013000 < PROTOBUF_MIN_PROTOC_VERSION
#error This file was generated by an older version of protoc which is #error This file was generated by an older version of protoc which is
#error incompatible with your Protocol Buffer headers. Please #error incompatible with your Protocol Buffer headers. Please
#error regenerate this file with a newer version of protoc. #error regenerate this file with a newer version of protoc.

@ -199,7 +199,7 @@ class FieldMaskTree {
// Remove a path from the tree. // Remove a path from the tree.
// If the path is a sub-path of an existing field path in the tree, it means // If the path is a sub-path of an existing field path in the tree, it means
// we need remove the existing fied path and add all sub-paths except // we need remove the existing field path and add all sub-paths except
// specified path. If the path matches an existing node in the tree, this node // specified path. If the path matches an existing node in the tree, this node
// will be moved. // will be moved.
void RemovePath(const std::string& path, const Descriptor* descriptor); void RemovePath(const std::string& path, const Descriptor* descriptor);
@ -332,7 +332,7 @@ void FieldMaskTree::AddPath(const std::string& path) {
for (int i = 0; i < parts.size(); ++i) { for (int i = 0; i < parts.size(); ++i) {
if (!new_branch && node != &root_ && node->children.empty()) { if (!new_branch && node != &root_ && node->children.empty()) {
// Path matches an existing leaf node. This means the path is already // Path matches an existing leaf node. This means the path is already
// coverred by this tree (for example, adding "foo.bar.baz" to a tree // covered by this tree (for example, adding "foo.bar.baz" to a tree
// which already contains "foo.bar"). // which already contains "foo.bar").
return; return;
} }
@ -707,7 +707,7 @@ bool FieldMaskUtil::TrimMessage(const FieldMask& mask, Message* message,
// fields. // fields.
FieldMaskTree tree; FieldMaskTree tree;
tree.MergeFromFieldMask(mask); tree.MergeFromFieldMask(mask);
// If keep_required_fields is true, implicitely add required fields of // If keep_required_fields is true, implicitly add required fields of
// a message present in the tree to prevent from trimming. // a message present in the tree to prevent from trimming.
if (options.keep_required_fields()) { if (options.keep_required_fields()) {
tree.AddRequiredFieldPath(GOOGLE_CHECK_NOTNULL(message->GetDescriptor())); tree.AddRequiredFieldPath(GOOGLE_CHECK_NOTNULL(message->GetDescriptor()));

@ -49,7 +49,7 @@ const char kRfc3339TimeFormat[] = "%E4Y-%m-%dT%H:%M:%S";
// timestamps like "1-01-0001T23:59:59Z" instead of "0001-01-0001T23:59:59Z". // timestamps like "1-01-0001T23:59:59Z" instead of "0001-01-0001T23:59:59Z".
const char kRfc3339TimeFormatNoPadding[] = "%Y-%m-%dT%H:%M:%S"; const char kRfc3339TimeFormatNoPadding[] = "%Y-%m-%dT%H:%M:%S";
// Minimun seconds allowed in a google.protobuf.Timestamp value. // Minimum seconds allowed in a google.protobuf.Timestamp value.
const int64 kTimestampMinSeconds = -62135596800LL; const int64 kTimestampMinSeconds = -62135596800LL;
// Maximum seconds allowed in a google.protobuf.Timestamp value. // Maximum seconds allowed in a google.protobuf.Timestamp value.

@ -152,7 +152,7 @@ class PROTOBUF_EXPORT JsonObjectWriter : public StructuredObjectWriter {
return false; return false;
} }
// Whether we are currently renderring inside a JSON object (i.e., between // Whether we are currently rendering inside a JSON object (i.e., between
// StartObject() and EndObject()). // StartObject() and EndObject()).
bool is_json_object() const { return is_json_object_; } bool is_json_object() const { return is_json_object_; }

@ -146,7 +146,7 @@ class JsonStreamParserTest : public ::testing::Test {
#ifndef _MSC_VER #ifndef _MSC_VER
// TODO(xiaofeng): We have to disable InSequence check for MSVC because it // TODO(xiaofeng): We have to disable InSequence check for MSVC because it
// causes stack overflow due to its use of a linked list that is desctructed // causes stack overflow due to its use of a linked list that is destructed
// recursively. // recursively.
::testing::InSequence in_sequence_; ::testing::InSequence in_sequence_;
#endif // !_MSC_VER #endif // !_MSC_VER

@ -63,7 +63,7 @@ class TypeInfoTestHelper {
// Creates a TypeInfo object for the given set of descriptors. // Creates a TypeInfo object for the given set of descriptors.
void ResetTypeInfo(const std::vector<const Descriptor*>& descriptors); void ResetTypeInfo(const std::vector<const Descriptor*>& descriptors);
// Convinent overloads. // Convenient overloads.
void ResetTypeInfo(const Descriptor* descriptor); void ResetTypeInfo(const Descriptor* descriptor);
void ResetTypeInfo(const Descriptor* descriptor1, void ResetTypeInfo(const Descriptor* descriptor1,
const Descriptor* descriptor2); const Descriptor* descriptor2);

@ -82,8 +82,8 @@ PROTOBUF_EXPORT std::string GetStringOptionOrDefault(
// Returns a boolean value contained in Any type. // Returns a boolean value contained in Any type.
// TODO(skarvaje): Make these utilities dealing with Any types more generic, // TODO(skarvaje): Make these utilities dealing with Any types more generic,
// add more error checking and move to a more public/sharable location so others // add more error checking and move to a more public/shareable location so
// can use. // others can use.
PROTOBUF_EXPORT bool GetBoolFromAny(const google::protobuf::Any& any); PROTOBUF_EXPORT bool GetBoolFromAny(const google::protobuf::Any& any);
// Returns int64 value contained in Any type. // Returns int64 value contained in Any type.

@ -933,26 +933,25 @@ bool MessageDifferencer::CompareMapFieldByMapReflection(
} }
const FieldDescriptor* val_des = map_field->message_type()->map_value(); const FieldDescriptor* val_des = map_field->message_type()->map_value();
switch (val_des->cpp_type()) { switch (val_des->cpp_type()) {
#define HANDLE_TYPE(CPPTYPE, METHOD, COMPAREMETHOD) \ #define HANDLE_TYPE(CPPTYPE, METHOD, COMPAREMETHOD) \
case FieldDescriptor::CPPTYPE_##CPPTYPE: { \ case FieldDescriptor::CPPTYPE_##CPPTYPE: { \
for (MapIterator it = reflection1->MapBegin( \ for (MapIterator it = reflection1->MapBegin( \
const_cast<Message*>(&message1), map_field); \ const_cast<Message*>(&message1), map_field); \
it != \ it != \
reflection1->MapEnd(const_cast<Message*>(&message1), map_field); \ reflection1->MapEnd(const_cast<Message*>(&message1), map_field); \
++it) { \ ++it) { \
if (!reflection2->ContainsMapKey(message2, map_field, it.GetKey())) { \ if (!reflection2->ContainsMapKey(message2, map_field, it.GetKey())) { \
return false; \ return false; \
} \ } \
MapValueRef value2; \ MapValueConstRef value2; \
reflection2->InsertOrLookupMapValue(const_cast<Message*>(&message2), \ reflection2->LookupMapValue(message2, map_field, it.GetKey(), &value2); \
map_field, it.GetKey(), &value2); \ if (!default_field_comparator_.Compare##COMPAREMETHOD( \
if (!default_field_comparator_.Compare##COMPAREMETHOD( \ *val_des, it.GetValueRef().Get##METHOD(), \
*val_des, it.GetValueRef().Get##METHOD(), \ value2.Get##METHOD())) { \
value2.Get##METHOD())) { \ return false; \
return false; \ } \
} \ } \
} \ break; \
break; \
} }
HANDLE_TYPE(INT32, Int32Value, Int32); HANDLE_TYPE(INT32, Int32Value, Int32);
HANDLE_TYPE(INT64, Int64Value, Int64); HANDLE_TYPE(INT64, Int64Value, Int64);
@ -973,9 +972,8 @@ bool MessageDifferencer::CompareMapFieldByMapReflection(
if (!reflection2->ContainsMapKey(message2, map_field, it.GetKey())) { if (!reflection2->ContainsMapKey(message2, map_field, it.GetKey())) {
return false; return false;
} }
MapValueRef value2; MapValueConstRef value2;
reflection2->InsertOrLookupMapValue(const_cast<Message*>(&message2), reflection2->LookupMapValue(message2, map_field, it.GetKey(), &value2);
map_field, it.GetKey(), &value2);
if (!Compare(it.GetValueRef().GetMessageValue(), if (!Compare(it.GetValueRef().GetMessageValue(),
value2.GetMessageValue())) { value2.GetMessageValue())) {
return false; return false;
@ -1220,7 +1218,8 @@ bool MessageDifferencer::IsTreatedAsSet(const FieldDescriptor* field) {
repeated_field_comparisons_.end()) { repeated_field_comparisons_.end()) {
return repeated_field_comparisons_[field] == AS_SET; return repeated_field_comparisons_[field] == AS_SET;
} }
return repeated_field_comparison_ == AS_SET; return GetMapKeyComparator(field) == nullptr &&
repeated_field_comparison_ == AS_SET;
} }
bool MessageDifferencer::IsTreatedAsSmartSet(const FieldDescriptor* field) { bool MessageDifferencer::IsTreatedAsSmartSet(const FieldDescriptor* field) {
@ -1229,7 +1228,8 @@ bool MessageDifferencer::IsTreatedAsSmartSet(const FieldDescriptor* field) {
repeated_field_comparisons_.end()) { repeated_field_comparisons_.end()) {
return repeated_field_comparisons_[field] == AS_SMART_SET; return repeated_field_comparisons_[field] == AS_SMART_SET;
} }
return repeated_field_comparison_ == AS_SMART_SET; return GetMapKeyComparator(field) == nullptr &&
repeated_field_comparison_ == AS_SMART_SET;
} }
bool MessageDifferencer::IsTreatedAsSmartList(const FieldDescriptor* field) { bool MessageDifferencer::IsTreatedAsSmartList(const FieldDescriptor* field) {
@ -1238,7 +1238,8 @@ bool MessageDifferencer::IsTreatedAsSmartList(const FieldDescriptor* field) {
repeated_field_comparisons_.end()) { repeated_field_comparisons_.end()) {
return repeated_field_comparisons_[field] == AS_SMART_LIST; return repeated_field_comparisons_[field] == AS_SMART_LIST;
} }
return repeated_field_comparison_ == AS_SMART_LIST; return GetMapKeyComparator(field) == nullptr &&
repeated_field_comparison_ == AS_SMART_LIST;
} }
bool MessageDifferencer::IsTreatedAsSubset(const FieldDescriptor* field) { bool MessageDifferencer::IsTreatedAsSubset(const FieldDescriptor* field) {
@ -1616,7 +1617,7 @@ int MaximumMatcher::FindMaximumMatch(bool early_return) {
} }
} }
// Backfill match_list1_ as we only filled match_list2_ when finding // Backfill match_list1_ as we only filled match_list2_ when finding
// argumenting pathes. // argumenting paths.
for (int i = 0; i < count2_; ++i) { for (int i = 0; i < count2_; ++i) {
if ((*match_list2_)[i] != -1) { if ((*match_list2_)[i] != -1) {
(*match_list1_)[(*match_list2_)[i]] = i; (*match_list1_)[(*match_list2_)[i]] = i;

@ -318,7 +318,7 @@ class PROTOBUF_EXPORT MessageDifferencer {
// Abstract base class from which all IgnoreCriteria derive. // Abstract base class from which all IgnoreCriteria derive.
// By adding IgnoreCriteria more complex ignore logic can be implemented. // By adding IgnoreCriteria more complex ignore logic can be implemented.
// IgnoreCriteria are registed with AddIgnoreCriteria. For each compared // IgnoreCriteria are registered with AddIgnoreCriteria. For each compared
// field IsIgnored is called on each added IgnoreCriteria until one returns // field IsIgnored is called on each added IgnoreCriteria until one returns
// true or all return false. // true or all return false.
// IsIgnored is called for fields where at least one side has a value. // IsIgnored is called for fields where at least one side has a value.

@ -67,7 +67,7 @@ namespace internal {
static size_t MapKeyDataOnlyByteSize(const FieldDescriptor* field, static size_t MapKeyDataOnlyByteSize(const FieldDescriptor* field,
const MapKey& value); const MapKey& value);
static size_t MapValueRefDataOnlyByteSize(const FieldDescriptor* field, static size_t MapValueRefDataOnlyByteSize(const FieldDescriptor* field,
const MapValueRef& value); const MapValueConstRef& value);
// =================================================================== // ===================================================================
@ -1099,7 +1099,7 @@ static uint8* SerializeMapKeyWithCachedSizes(const FieldDescriptor* field,
} }
static uint8* SerializeMapValueRefWithCachedSizes( static uint8* SerializeMapValueRefWithCachedSizes(
const FieldDescriptor* field, const MapValueRef& value, uint8* target, const FieldDescriptor* field, const MapValueConstRef& value, uint8* target,
io::EpsCopyOutputStream* stream) { io::EpsCopyOutputStream* stream) {
target = stream->EnsureSpace(target); target = stream->EnsureSpace(target);
switch (field->type()) { switch (field->type()) {
@ -1184,7 +1184,8 @@ class MapKeySorter {
static uint8* InternalSerializeMapEntry(const FieldDescriptor* field, static uint8* InternalSerializeMapEntry(const FieldDescriptor* field,
const MapKey& key, const MapKey& key,
const MapValueRef& value, uint8* target, const MapValueConstRef& value,
uint8* target,
io::EpsCopyOutputStream* stream) { io::EpsCopyOutputStream* stream) {
const FieldDescriptor* key_field = field->message_type()->field(0); const FieldDescriptor* key_field = field->message_type()->field(0);
const FieldDescriptor* value_field = field->message_type()->field(1); const FieldDescriptor* value_field = field->message_type()->field(1);
@ -1237,9 +1238,8 @@ uint8* WireFormat::InternalSerializeField(const FieldDescriptor* field,
MapKeySorter::SortKey(message, message_reflection, field); MapKeySorter::SortKey(message, message_reflection, field);
for (std::vector<MapKey>::iterator it = sorted_key_list.begin(); for (std::vector<MapKey>::iterator it = sorted_key_list.begin();
it != sorted_key_list.end(); ++it) { it != sorted_key_list.end(); ++it) {
MapValueRef map_value; MapValueConstRef map_value;
message_reflection->InsertOrLookupMapValue( message_reflection->LookupMapValue(message, field, *it, &map_value);
const_cast<Message*>(&message), field, *it, &map_value);
target = target =
InternalSerializeMapEntry(field, *it, map_value, target, stream); InternalSerializeMapEntry(field, *it, map_value, target, stream);
} }
@ -1566,7 +1566,7 @@ static size_t MapKeyDataOnlyByteSize(const FieldDescriptor* field,
} }
static size_t MapValueRefDataOnlyByteSize(const FieldDescriptor* field, static size_t MapValueRefDataOnlyByteSize(const FieldDescriptor* field,
const MapValueRef& value) { const MapValueConstRef& value) {
switch (field->type()) { switch (field->type()) {
case FieldDescriptor::TYPE_GROUP: case FieldDescriptor::TYPE_GROUP:
GOOGLE_LOG(FATAL) << "Unsupported"; GOOGLE_LOG(FATAL) << "Unsupported";

@ -8,12 +8,12 @@
#include <string> #include <string>
#include <google/protobuf/port_def.inc> #include <google/protobuf/port_def.inc>
#if PROTOBUF_VERSION < 3012000 #if PROTOBUF_VERSION < 3013000
#error This file was generated by a newer version of protoc which is #error This file was generated by a newer version of protoc which is
#error incompatible with your Protocol Buffer headers. Please update #error incompatible with your Protocol Buffer headers. Please update
#error your headers. #error your headers.
#endif #endif
#if 3012003 < PROTOBUF_MIN_PROTOC_VERSION #if 3013000 < PROTOBUF_MIN_PROTOC_VERSION
#error This file was generated by an older version of protoc which is #error This file was generated by an older version of protoc which is
#error incompatible with your Protocol Buffer headers. Please #error incompatible with your Protocol Buffer headers. Please
#error regenerate this file with a newer version of protoc. #error regenerate this file with a newer version of protoc.

@ -101,6 +101,9 @@ def UpdateConfigure():
def UpdateCpp(): def UpdateCpp():
cpp_version = '%d%03d%03d' % ( cpp_version = '%d%03d%03d' % (
NEW_VERSION_INFO[0], NEW_VERSION_INFO[1], NEW_VERSION_INFO[2]) NEW_VERSION_INFO[0], NEW_VERSION_INFO[1], NEW_VERSION_INFO[2])
version_suffix = ''
if RC_VERSION != -1:
version_suffix = '-rc%s' % RC_VERSION
def RewriteCommon(line): def RewriteCommon(line):
line = re.sub( line = re.sub(
r'^#define GOOGLE_PROTOBUF_VERSION .*$', r'^#define GOOGLE_PROTOBUF_VERSION .*$',
@ -110,6 +113,14 @@ def UpdateCpp():
r'^#define PROTOBUF_VERSION .*$', r'^#define PROTOBUF_VERSION .*$',
'#define PROTOBUF_VERSION %s' % cpp_version, '#define PROTOBUF_VERSION %s' % cpp_version,
line) line)
line = re.sub(
r'^#define GOOGLE_PROTOBUF_VERSION_SUFFIX .*$',
'#define GOOGLE_PROTOBUF_VERSION_SUFFIX "%s"' % version_suffix,
line)
line = re.sub(
r'^#define PROTOBUF_VERSION_SUFFIX .*$',
'#define PROTOBUF_VERSION_SUFFIX "%s"' % version_suffix,
line)
if NEW_VERSION_INFO[2] == 0: if NEW_VERSION_INFO[2] == 0:
line = re.sub( line = re.sub(
r'^#define PROTOBUF_MIN_HEADER_VERSION_FOR_PROTOC .*$', r'^#define PROTOBUF_MIN_HEADER_VERSION_FOR_PROTOC .*$',
@ -128,12 +139,16 @@ def UpdateCpp():
'static const int kMinHeaderVersionForProtoc = %s;' % cpp_version, 'static const int kMinHeaderVersionForProtoc = %s;' % cpp_version,
line) line)
return line return line
def RewritePortDef(line): def RewritePortDef(line):
line = re.sub( line = re.sub(
r'^#define PROTOBUF_VERSION .*$', r'^#define PROTOBUF_VERSION .*$',
'#define PROTOBUF_VERSION %s' % cpp_version, '#define PROTOBUF_VERSION %s' % cpp_version,
line) line)
line = re.sub(
r'^#define PROTOBUF_VERSION_SUFFIX .*$',
'#define PROTOBUF_VERSION_SUFFIX "%s"' % version_suffix,
line)
if NEW_VERSION_INFO[2] == 0: if NEW_VERSION_INFO[2] == 0:
line = re.sub( line = re.sub(
r'^#define PROTOBUF_MIN_HEADER_VERSION_FOR_PROTOC .*$', r'^#define PROTOBUF_MIN_HEADER_VERSION_FOR_PROTOC .*$',
@ -302,7 +317,7 @@ def UpdatePhp():
FindAndClone(root, 'date'), FindAndClone(root, 'date'),
FindAndClone(root, 'time'), FindAndClone(root, 'time'),
FindAndClone(root, 'license'), FindAndClone(root, 'license'),
FindAndClone(root, 'notes') CreateNode('notes', 3, []),
]) ])
changelog.appendChild(release) changelog.appendChild(release)
changelog.appendChild(document.createTextNode('\n ')) changelog.appendChild(document.createTextNode('\n '))

Loading…
Cancel
Save