Эх сурвалжийг харах

Sync from Piper @328224070

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

+ 1 - 1
.github/workflows/codespell.yml

@@ -12,5 +12,5 @@ jobs:
       - uses: codespell-project/actions-codespell@master
         with:
           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"

+ 1 - 0
BUILD

@@ -175,6 +175,7 @@ cc_library(
         "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_lite.cc",
+        "src/google/protobuf/map.cc",
         "src/google/protobuf/message_lite.cc",
         "src/google/protobuf/parse_context.cc",
         "src/google/protobuf/repeated_field.cc",

+ 47 - 1
CHANGES.txt

@@ -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++:
   * Removed deprecated unsafe arena string accessors
@@ -51,6 +92,11 @@
     performance (the legacy generated code will still work, but might incur
     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)
 
   Objective-C

+ 13 - 11
Makefile.am

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

+ 1 - 1
Protobuf-C++.podspec

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

+ 6 - 6
benchmarks/js/js_benchmark.js

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

+ 6 - 6
benchmarks/protobuf.js/protobufjs_benchmark.js

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

+ 1 - 1
cmake/CMakeLists.txt

@@ -29,7 +29,7 @@ else()
 endif()
 
 # 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"
 # This silences that warning.
 if (CMAKE_CXX_COMPILER_ID MATCHES Intel)

+ 2 - 2
cmake/protobuf-options.cmake

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

+ 1 - 1
configure.ac

@@ -17,7 +17,7 @@ AC_PREREQ(2.59)
 # 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
 # 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])
 

+ 2 - 2
conformance/conformance.proto

@@ -64,7 +64,7 @@ enum TestCategory {
   BINARY_TEST = 1;  // Test binary wire format.
   JSON_TEST = 2;    // Test json wire format.
   // 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
   // https://developers.google.com/protocol-buffers/docs/proto3#json_options
   // for more detail.
@@ -113,7 +113,7 @@ message ConformanceRequest {
   string message_type = 4;
 
   // 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.
   TestCategory test_category = 5;
 

+ 2 - 0
conformance/failure_list_php_c.txt

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

+ 2 - 0
conformance/failure_list_php_c_32.txt

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

+ 3 - 0
conformance/failure_list_ruby.txt

@@ -8,6 +8,9 @@ Recommended.Proto3.JsonInput.DurationHas3FractionalDigits.Validator
 Recommended.Proto3.JsonInput.DurationHas6FractionalDigits.Validator
 Recommended.Proto3.JsonInput.FieldMaskInvalidCharacter
 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.RepeatedFieldPrimitiveElementIsNull
 Recommended.Proto3.JsonInput.StringEndsWithEscapeChar

+ 2 - 2
csharp/src/Google.Protobuf.Conformance/Conformance.cs

@@ -82,7 +82,7 @@ namespace Conformance {
     [pbr::OriginalName("JSON_TEST")] JsonTest = 2,
     /// <summary>
     /// 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
     /// https://developers.google.com/protocol-buffers/docs/proto3#json_options
     /// for more detail.
@@ -414,7 +414,7 @@ namespace Conformance {
     private global::Conformance.TestCategory testCategory_ = global::Conformance.TestCategory.UnspecifiedTest;
     /// <summary>
     /// 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.
     /// </summary>
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]

BIN
csharp/src/Google.Protobuf.Test/testprotos.pb


+ 2 - 2
csharp/src/Google.Protobuf/UnknownField.cs

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

+ 1 - 1
csharp/src/Google.Protobuf/WellKnownTypes/Api.cs

@@ -918,7 +918,7 @@ namespace Google.Protobuf.WellKnownTypes {
   /// The mixin construct implies that all methods in `AccessControl` are
   /// also declared with same name and request/response types in
   /// `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:
   ///
   ///     service Storage {

+ 1 - 1
java/README.md

@@ -45,7 +45,7 @@ protobuf-java-util package:
 
 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.
 

+ 1 - 1
java/compatibility_tests/v2.5.0/more_protos/src/proto/google/protobuf/descriptor.proto

@@ -74,7 +74,7 @@ message FileDescriptorProto {
   optional FileOptions options = 8;
 
   // 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
   // development tools.
   optional SourceCodeInfo source_code_info = 9;

+ 1 - 1
java/compatibility_tests/v2.5.0/protos/src/proto/google/protobuf/descriptor.proto

@@ -74,7 +74,7 @@ message FileDescriptorProto {
   optional FileOptions options = 8;
 
   // 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
   // development tools.
   optional SourceCodeInfo source_code_info = 9;

+ 2 - 2
java/core/src/main/java/com/google/protobuf/ArrayDecoders.java

@@ -39,7 +39,7 @@ import java.io.IOException;
  * 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
- * 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
  * 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.
    *
    * <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 {
     public int int1;

+ 1 - 1
java/core/src/main/java/com/google/protobuf/Descriptors.java

@@ -1084,7 +1084,7 @@ public final class Descriptors {
 
     /**
      * 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
     public boolean isPacked() {

+ 1 - 1
java/core/src/main/java/com/google/protobuf/GeneratedMessageLite.java

@@ -223,7 +223,7 @@ public abstract class GeneratedMessageLite<
 
   /**
    * 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
    * count.
    *

+ 1 - 1
java/core/src/main/java/com/google/protobuf/MapEntryLite.java

@@ -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}.
    */
   public void parseInto(

+ 7 - 0
java/core/src/test/java/com/google/protobuf/ExtensionRegistryFactoryTest.java

@@ -41,6 +41,7 @@ import java.util.Set;
 import junit.framework.Test;
 import junit.framework.TestCase;
 import junit.framework.TestSuite;
+import org.junit.Ignore;
 
 /**
  * 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
  * 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 {
 
   // A classloader which blacklists some non-Lite classes.

+ 16 - 0
java/lite.md

@@ -34,6 +34,22 @@ protobuf Java runtime. If you are using Maven, use the following:
 </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:
 
     https://github.com/protocolbuffers/protobuf/blob/javalite/java/lite.md

+ 1 - 1
js/binary/utils.js

@@ -258,7 +258,7 @@ jspb.utils.splitFloat64 = function(value) {
   // Compute the least significant exponent needed to represent the magnitude of
   // 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
-  // bounadaries of precision, the result can be off by one.
+  // boundaries of precision, the result can be off by one.
   var maxDoubleExponent = 1023;
   var minDoubleExponent = -1022;
   var x = value;

+ 1 - 1
js/package.json

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

+ 1 - 1
objectivec/GPBApi.pbobjc.h

@@ -257,7 +257,7 @@ typedef GPB_ENUM(GPBMixin_FieldNumber) {
  * The mixin construct implies that all methods in `AccessControl` are
  * also declared with same name and request/response types in
  * `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:
  *
  *     service Storage {

+ 1 - 0
protobuf.bzl

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

+ 1 - 1
python/compatibility_tests/v2.5.0/protos/src/proto/google/protobuf/descriptor.proto

@@ -74,7 +74,7 @@ message FileDescriptorProto {
   optional FileOptions options = 8;
 
   // 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
   // development tools.
   optional SourceCodeInfo source_code_info = 9;

+ 1 - 1
python/google/protobuf/__init__.py

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

+ 3 - 2
python/google/protobuf/descriptor.py

@@ -227,7 +227,8 @@ class _NestedDescriptorBase(DescriptorBase):
       proto: An empty proto instance from descriptor_pb2.
 
     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
         self._serialized_start is not None and
@@ -827,7 +828,7 @@ class ServiceDescriptor(_NestedDescriptorBase):
     Args:
       name (str): Name of the method.
     Returns:
-      MethodDescriptor or None: the desctiptor for the requested method, if
+      MethodDescriptor or None: the descriptor for the requested method, if
       found.
     """
     return self.methods_by_name.get(name, None)

+ 1 - 1
python/google/protobuf/descriptor_database.py

@@ -58,7 +58,7 @@ class DescriptorDatabase(object):
     Raises:
       DescriptorDatabaseConflictingDefinitionError: if an attempt is made to
         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
     if proto_name not in self._file_desc_protos_by_file:

+ 1 - 1
python/google/protobuf/internal/json_format_test.py

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

+ 1 - 1
python/google/protobuf/internal/message_test.py

@@ -1059,7 +1059,7 @@ class MessageTest(unittest.TestCase):
     self.assertIsInstance(m.optional_string, six.text_type)
 
   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.
     """

+ 2 - 2
python/google/protobuf/internal/reflection_test.py

@@ -2813,7 +2813,7 @@ class SerializationTest(unittest.TestCase):
         proto2.MergeFromString(serialized))
 
   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:
       callable_obj()
     except exc_class as ex:
@@ -3267,7 +3267,7 @@ class ClassAPITest(unittest.TestCase):
   # conflicting message descriptors.
   def testParsingFlatClassWithExplicitClassDeclaration(self):
     """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
     # 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

+ 1 - 1
python/google/protobuf/internal/well_known_types.py

@@ -401,7 +401,7 @@ def _CheckDurationValid(seconds, nanos):
 
 def _RoundTowardZero(value, divider):
   """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
   # "rounded toward zero" semantics. For example, for (-5) / 2 an
   # implementation may give -3 as the result with the remainder being

+ 1 - 1
python/google/protobuf/pyext/scoped_pyobject_ptr.h

@@ -77,7 +77,7 @@ class ScopedPythonPtr {
 
   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.
   void inc() const { Py_INCREF(ptr_); }
 

+ 1 - 1
src/Makefile.am

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

+ 2 - 2
src/google/protobuf/any.pb.h

@@ -8,12 +8,12 @@
 #include <string>
 
 #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 incompatible with your Protocol Buffer headers. Please update
 #error your headers.
 #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 incompatible with your Protocol Buffer headers. Please
 #error regenerate this file with a newer version of protoc.

+ 2 - 2
src/google/protobuf/api.pb.h

@@ -8,12 +8,12 @@
 #include <string>
 
 #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 incompatible with your Protocol Buffer headers. Please update
 #error your headers.
 #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 incompatible with your Protocol Buffer headers. Please
 #error regenerate this file with a newer version of protoc.

+ 1 - 1
src/google/protobuf/api.proto

@@ -167,7 +167,7 @@ message Method {
 // The mixin construct implies that all methods in `AccessControl` are
 // also declared with same name and request/response types in
 // `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:
 //
 //     service Storage {

+ 1 - 1
src/google/protobuf/arena_test_util.h

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

+ 4 - 1
src/google/protobuf/compiler/command_line_interface.cc

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

+ 1 - 1
src/google/protobuf/compiler/command_line_interface.h

@@ -104,7 +104,7 @@ class DiskSourceTree;    // importer.h
 //   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
-// 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.
 class PROTOC_EXPORT CommandLineInterface {

+ 2 - 5
src/google/protobuf/compiler/cpp/cpp_helpers.cc

@@ -1415,9 +1415,7 @@ class ParseLoopGenerator {
       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);
     format_.Outdent();
     format_("success:\n");
@@ -1469,8 +1467,7 @@ class ParseLoopGenerator {
       // Open source doesn't support other ctypes;
       ctype = field->options().ctype();
     }
-    if (field->file()->options().cc_enable_arenas() && !field->is_repeated() &&
-        !options_.opensource_runtime &&
+    if (!field->is_repeated() && !options_.opensource_runtime &&
         GetOptimizeFor(field->file(), options_) != FileOptions::LITE_RUNTIME &&
         // For now only use arena string for strings with empty defaults.
         field->default_value_string().empty() &&

+ 1 - 1
src/google/protobuf/compiler/cpp/cpp_message.h

@@ -105,7 +105,7 @@ class MessageGenerator {
   bool GenerateParseTable(io::Printer* printer, size_t 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.
   std::pair<size_t, size_t> GenerateOffsets(io::Printer* printer);
   void GenerateSchema(io::Printer* printer, int offset, int has_offset);

+ 3 - 2
src/google/protobuf/compiler/importer_unittest.cc

@@ -463,13 +463,14 @@ TEST_F(DiskSourceTreeTest, DiskFileToVirtualFileCanonicalization) {
             source_tree_.DiskFileToVirtualFile("../../baz", &virtual_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,
             source_tree_.DiskFileToVirtualFile("/foo", &virtual_file,
                                                &shadowing_disk_file));
 
 #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,
             source_tree_.DiskFileToVirtualFile("C:\\foo", &virtual_file,
                                                &shadowing_disk_file));

+ 1 - 1
src/google/protobuf/compiler/java/java_enum_field.cc

@@ -712,7 +712,7 @@ void RepeatedImmutableEnumFieldGenerator::GenerateBuilderMembers(
       // list is immutable. If it's immutable, the invariant is that it must
       // either an instance of Collections.emptyList() or it's an ArrayList
       // 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
       // memory allocations. Note, immutable is a strong guarantee here -- not
       // just that the list cannot be modified via the reference but that the

+ 1 - 1
src/google/protobuf/compiler/java/java_message_field.cc

@@ -944,7 +944,7 @@ void RepeatedImmutableMessageFieldGenerator::GenerateBuilderMembers(
       // list is immutable. If it's immutable, the invariant is that it must
       // either an instance of Collections.emptyList() or it's an ArrayList
       // 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
       // memory allocations. Note, immutable is a strong guarantee here -- not
       // just that the list cannot be modified via the reference but that the

+ 1 - 1
src/google/protobuf/compiler/java/java_primitive_field.cc

@@ -703,7 +703,7 @@ void RepeatedImmutablePrimitiveFieldGenerator::GenerateBuilderMembers(
   // list is immutable. If it's immutable, the invariant is that it must
   // either an instance of Collections.emptyList() or it's an ArrayList
   // 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
   // memory allocations. Note, immutable is a strong guarantee here -- not
   // just that the list cannot be modified via the reference but that the

+ 1 - 1
src/google/protobuf/compiler/java/java_string_field.cc

@@ -801,7 +801,7 @@ void RepeatedImmutableStringFieldGenerator::GenerateBuilderMembers(
   // list is immutable. If it's immutable, the invariant is that it must
   // either an instance of Collections.emptyList() or it's an ArrayList
   // 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
   // memory allocations. Note, immutable is a strong guarantee here -- not
   // just that the list cannot be modified via the reference but that the

+ 2 - 0
src/google/protobuf/compiler/js/js_generator.cc

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

+ 2 - 2
src/google/protobuf/compiler/js/js_generator.h

@@ -125,10 +125,10 @@ struct GeneratorOptions {
   std::string extension;
   // Create a separate output file for each 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
   // 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).
   bool annotate_code;
 };

+ 2 - 2
src/google/protobuf/compiler/plugin.pb.h

@@ -8,12 +8,12 @@
 #include <string>
 
 #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 incompatible with your Protocol Buffer headers. Please update
 #error your headers.
 #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 incompatible with your Protocol Buffer headers. Please
 #error regenerate this file with a newer version of protoc.

+ 1 - 1
src/google/protobuf/compiler/python/python_generator.cc

@@ -1067,7 +1067,7 @@ void Generator::FixContainingTypeInDescriptor(
 }
 
 // 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
 // just set everything in the initial assignment statements).
 void Generator::FixForeignFieldsInDescriptors() const {

+ 1 - 1
src/google/protobuf/descriptor.cc

@@ -6133,7 +6133,7 @@ void DescriptorBuilder::ValidateFieldOptions(
 
   // json_name option is not allowed on extension fields. Note that the
   // 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
   // determine whether the json_name option is set on the field. Here we
   // compare it against the default calculated json_name value and consider

+ 2 - 2
src/google/protobuf/descriptor.pb.h

@@ -8,12 +8,12 @@
 #include <string>
 
 #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 incompatible with your Protocol Buffer headers. Please update
 #error your headers.
 #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 incompatible with your Protocol Buffer headers. Please
 #error regenerate this file with a newer version of protoc.

+ 1 - 1
src/google/protobuf/descriptor_unittest.cc

@@ -479,7 +479,7 @@ TEST_F(FileDescriptorTest, FindExtensionByNumber) {
 
 
 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.
   FileDescriptorProto file;
   foo_file_->CopyTo(&file);

+ 2 - 2
src/google/protobuf/duration.pb.h

@@ -8,12 +8,12 @@
 #include <string>
 
 #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 incompatible with your Protocol Buffer headers. Please update
 #error your headers.
 #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 incompatible with your Protocol Buffer headers. Please
 #error regenerate this file with a newer version of protoc.

+ 2 - 2
src/google/protobuf/empty.pb.h

@@ -8,12 +8,12 @@
 #include <string>
 
 #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 incompatible with your Protocol Buffer headers. Please update
 #error your headers.
 #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 incompatible with your Protocol Buffer headers. Please
 #error regenerate this file with a newer version of protoc.

+ 2 - 2
src/google/protobuf/field_mask.pb.h

@@ -8,12 +8,12 @@
 #include <string>
 
 #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 incompatible with your Protocol Buffer headers. Please update
 #error your headers.
 #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 incompatible with your Protocol Buffer headers. Please
 #error regenerate this file with a newer version of protoc.

+ 10 - 1
src/google/protobuf/generated_message_reflection.cc

@@ -853,7 +853,7 @@ void Reflection::ClearField(Message* 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
             // to nullptr in order to indicate its un-presence.
             if (GetArena(message) == nullptr) {
@@ -1884,6 +1884,15 @@ bool Reflection::InsertOrLookupMapValue(Message* message,
       ->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,
                                 const MapKey& key) const {
   USAGE_CHECK(IsMapFieldInApi(field), "DeleteMapValue",

+ 1 - 1
src/google/protobuf/generated_message_table_driven.h

@@ -102,7 +102,7 @@ struct PROTOBUF_EXPORT FieldMetadata {
     kNumTypeClasses  // must be last enum
   };
   // 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 {
     kCordType = 19,
     kStringPieceType = 20,

+ 2 - 2
src/google/protobuf/io/coded_stream.h

@@ -960,7 +960,7 @@ class PROTOBUF_EXPORT EpsCopyOutputStream {
   // buffers to ensure there is no error as of yet.
   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
   // the old CodedOutputStream and then return to normal operation.
   bool Skip(int count, uint8** pp);
@@ -1159,7 +1159,7 @@ class PROTOBUF_EXPORT CodedOutputStream {
   // This is identical to WriteVarint32(), but optimized for writing tags.
   // In particular, if the input is a compile-time constant, this method
   // 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.
   void WriteTag(uint32 value);
   // Like WriteTag()  but writing directly to the target array.

+ 1 - 1
src/google/protobuf/io/zero_copy_stream_unittest.cc

@@ -112,7 +112,7 @@ class IoTest : public testing::Test {
   // that it matches the string.
   void ReadString(ZeroCopyInputStream* input, const std::string& str);
   // 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.
   int WriteStuff(ZeroCopyOutputStream* output);
   // Reads text from an input stream and expects it to match what

+ 1 - 1
src/google/protobuf/map.h

@@ -445,7 +445,7 @@ class Map {
   // 9. Except for erase(iterator), any non-const method can reorder iterators.
   // 10. InnerMap uses KeyForTree<Key> when using the Tree representation, which
   //    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 {
    public:
     explicit InnerMap(Arena* arena)

+ 26 - 0
src/google/protobuf/map_field.cc

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

+ 123 - 72
src/google/protobuf/map_field.h

@@ -319,7 +319,7 @@ class MapFieldAccessor;
 
 // This class provides access to map field using reflection, which is the same
 // 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 {
  public:
   MapFieldBase()
@@ -346,6 +346,10 @@ class PROTOBUF_EXPORT MapFieldBase {
   virtual bool ContainsMapKey(const MapKey& map_key) const = 0;
   virtual bool InsertOrLookupMapValue(const MapKey& map_key,
                                       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.
   bool IsRepeatedFieldValid() const;
   // 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.
   void SetMapDirty();
 
-  // Tells MapFieldBase that there is new change to RepeatedPTrField.
+  // Tells MapFieldBase that there is new change to RepeatedPtrField.
   void SetRepeatedDirty();
 
   // Provides derived class the access to repeated field.
   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 {
     STATE_MODIFIED_MAP = 0,       // map has newly added data that has not been
                                   // 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
-// internal generated message implentation only. Users should never use this
+// internal generated message implementation only. Users should never use this
 // directly.
 template <typename Derived, typename Key, typename T,
           WireFormatLite::FieldType kKeyFieldType,
@@ -504,6 +527,9 @@ class MapField : public TypeDefinedMapFieldBase<Key, T> {
   // Implement MapFieldBase
   bool ContainsMapKey(const MapKey& map_key) const 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;
 
   const Map<Key, T>& GetMap() const override {
@@ -597,6 +623,9 @@ class PROTOBUF_EXPORT DynamicMapField
   // Implement MapFieldBase
   bool ContainsMapKey(const MapKey& map_key) const 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;
   void MergeFrom(const MapFieldBase& other) override;
   void Swap(MapFieldBase* other) override;
@@ -623,96 +652,76 @@ class PROTOBUF_EXPORT DynamicMapField
 
 }  // namespace internal
 
-// MapValueRef points to a map value.
-class PROTOBUF_EXPORT MapValueRef {
+// MapValueConstRef points to a map value. Users can NOT modify
+// the map value.
+class PROTOBUF_EXPORT MapValueConstRef {
  public:
-  MapValueRef() : data_(NULL), 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;
-  }
+  MapValueConstRef() : data_(nullptr), type_(0) {}
 
   int64 GetInt64Value() const {
-    TYPE_CHECK(FieldDescriptor::CPPTYPE_INT64, "MapValueRef::GetInt64Value");
+    TYPE_CHECK(FieldDescriptor::CPPTYPE_INT64,
+               "MapValueConstRef::GetInt64Value");
     return *reinterpret_cast<int64*>(data_);
   }
   uint64 GetUInt64Value() const {
-    TYPE_CHECK(FieldDescriptor::CPPTYPE_UINT64, "MapValueRef::GetUInt64Value");
+    TYPE_CHECK(FieldDescriptor::CPPTYPE_UINT64,
+               "MapValueConstRef::GetUInt64Value");
     return *reinterpret_cast<uint64*>(data_);
   }
   int32 GetInt32Value() const {
-    TYPE_CHECK(FieldDescriptor::CPPTYPE_INT32, "MapValueRef::GetInt32Value");
+    TYPE_CHECK(FieldDescriptor::CPPTYPE_INT32,
+               "MapValueConstRef::GetInt32Value");
     return *reinterpret_cast<int32*>(data_);
   }
   uint32 GetUInt32Value() const {
-    TYPE_CHECK(FieldDescriptor::CPPTYPE_UINT32, "MapValueRef::GetUInt32Value");
+    TYPE_CHECK(FieldDescriptor::CPPTYPE_UINT32,
+               "MapValueConstRef::GetUInt32Value");
     return *reinterpret_cast<uint32*>(data_);
   }
   bool GetBoolValue() const {
-    TYPE_CHECK(FieldDescriptor::CPPTYPE_BOOL, "MapValueRef::GetBoolValue");
+    TYPE_CHECK(FieldDescriptor::CPPTYPE_BOOL, "MapValueConstRef::GetBoolValue");
     return *reinterpret_cast<bool*>(data_);
   }
   int GetEnumValue() const {
-    TYPE_CHECK(FieldDescriptor::CPPTYPE_ENUM, "MapValueRef::GetEnumValue");
+    TYPE_CHECK(FieldDescriptor::CPPTYPE_ENUM, "MapValueConstRef::GetEnumValue");
     return *reinterpret_cast<int*>(data_);
   }
   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_);
   }
   float GetFloatValue() const {
-    TYPE_CHECK(FieldDescriptor::CPPTYPE_FLOAT, "MapValueRef::GetFloatValue");
+    TYPE_CHECK(FieldDescriptor::CPPTYPE_FLOAT,
+               "MapValueConstRef::GetFloatValue");
     return *reinterpret_cast<float*>(data_);
   }
   double GetDoubleValue() const {
-    TYPE_CHECK(FieldDescriptor::CPPTYPE_DOUBLE, "MapValueRef::GetDoubleValue");
+    TYPE_CHECK(FieldDescriptor::CPPTYPE_DOUBLE,
+               "MapValueConstRef::GetDoubleValue");
     return *reinterpret_cast<double*>(data_);
   }
 
   const Message& GetMessageValue() const {
     TYPE_CHECK(FieldDescriptor::CPPTYPE_MESSAGE,
-               "MapValueRef::GetMessageValue");
+               "MapValueConstRef::GetMessageValue");
     return *reinterpret_cast<Message*>(data_);
   }
 
-  Message* MutableMessageValue() {
-    TYPE_CHECK(FieldDescriptor::CPPTYPE_MESSAGE,
-               "MapValueRef::MutableMessageValue");
-    return reinterpret_cast<Message*>(data_);
+ protected:
+  // data_ point to a map value. MapValueConstRef does not
+  // own this value.
+  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:
@@ -727,19 +736,66 @@ class PROTOBUF_EXPORT MapValueRef {
   friend class internal::DynamicMapField;
 
   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 CopyFrom(const MapValueRef& other) {
+  void CopyFrom(const MapValueConstRef& other) {
     type_ = other.type_;
     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
   void DeleteData() {
     switch (type_) {
@@ -761,11 +817,6 @@ class PROTOBUF_EXPORT MapValueRef {
 #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

+ 17 - 0
src/google/protobuf/map_field_inl.h

@@ -234,6 +234,23 @@ bool MapField<Derived, Key, T, kKeyFieldType,
   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,
           WireFormatLite::FieldType kKeyFieldType,
           WireFormatLite::FieldType kValueFieldType>

+ 1 - 1
src/google/protobuf/map_field_lite.h

@@ -50,7 +50,7 @@ namespace protobuf {
 namespace internal {
 
 // 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.
 template <typename Derived, typename Key, typename T,
           WireFormatLite::FieldType key_wire_type,

+ 4 - 0
src/google/protobuf/map_field_test.cc

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

+ 7 - 6
src/google/protobuf/map_test.cc

@@ -234,9 +234,10 @@ TEST_F(MapImplTest, UsageErrors) {
                "  Actual   : int64");
 
   MapValueRef value;
-  EXPECT_DEATH(value.SetFloatValue(0.1),
-               "Protocol Buffer map usage error:\n"
-               "MapValueRef::type MapValueRef is not initialized.");
+  EXPECT_DEATH(
+      value.SetFloatValue(0.1),
+      "Protocol Buffer map usage error:\n"
+      "MapValue[Const]*Ref::type MapValue[Const]*Ref is not initialized.");
 }
 
 #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
   // repeated field to calculate ByteSizeLong but use map to serialize the real
   // data, thus the ByteSizeLong may bigger than real serialized size. A crash
-  // might be happen at SerializeToString(). Or an "unexpect end group" warning
-  // was raised at parse back if user use SerializeWithCachedSizes() which
-  // avoids size check at serialize.
+  // might be happen at SerializeToString(). Or an "unexpected end group"
+  // warning was raised at parse back if user use SerializeWithCachedSizes()
+  // which avoids size check at serialize.
   std::string serialized_data;
   dynamic_message->SerializeToString(&serialized_data);
   EXPECT_EQ(serialized_data, expected_serialized_data);

+ 72 - 0
src/google/protobuf/map_test_util.h

@@ -495,20 +495,27 @@ inline void MapReflectionTester::SetMapFieldsViaMapReflection(
 
   Message* sub_foreign_message = nullptr;
   MapValueRef map_val;
+  MapValueConstRef map_val_const;
 
   // Add first element.
   MapKey map_key;
   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"),
                                                  map_key, &map_val));
   map_val.SetInt32Value(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"),
                                                  map_key, &map_val));
   map_val.SetInt64Value(0);
 
   map_key.SetUInt32Value(0);
+  EXPECT_FALSE(reflection->LookupMapValue(*message, F("map_uint32_uint32"),
+                                          map_key, &map_val_const));
   EXPECT_TRUE(reflection->InsertOrLookupMapValue(
       message, F("map_uint32_uint32"), map_key, &map_val));
   map_val.SetUInt32Value(0);
@@ -559,26 +566,36 @@ inline void MapReflectionTester::SetMapFieldsViaMapReflection(
   map_val.SetDoubleValue(0.0);
 
   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"),
                                                  map_key, &map_val));
   map_val.SetBoolValue(false);
 
   map_key.SetStringValue("0");
+  EXPECT_FALSE(reflection->LookupMapValue(*message, F("map_string_string"),
+                                          map_key, &map_val_const));
   EXPECT_TRUE(reflection->InsertOrLookupMapValue(
       message, F("map_string_string"), map_key, &map_val));
   map_val.SetStringValue("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"),
                                                  map_key, &map_val));
   map_val.SetStringValue("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"),
                                                  map_key, &map_val));
   map_val.SetEnumValue(map_enum_bar_->number());
 
   map_key.SetInt32Value(0);
+  EXPECT_FALSE(reflection->LookupMapValue(
+      *message, F("map_int32_foreign_message"), map_key, &map_val_const));
   EXPECT_TRUE(reflection->InsertOrLookupMapValue(
       message, F("map_int32_foreign_message"), map_key, &map_val));
   sub_foreign_message = map_val.MutableMessageValue();
@@ -933,6 +950,7 @@ inline void MapReflectionTester::ExpectMapFieldsSetViaReflection(
   const Reflection* reflection = message.GetReflection();
   const Message* sub_message;
   MapKey map_key;
+  MapValueConstRef map_value_const_ref;
 
   // -----------------------------------------------------------------
 
@@ -971,6 +989,9 @@ inline void MapReflectionTester::ExpectMapFieldsSetViaReflection(
       map_key.SetInt32Value(key);
       EXPECT_TRUE(
           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);
       EXPECT_TRUE(
           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);
       EXPECT_TRUE(
           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);
       EXPECT_TRUE(
           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);
       EXPECT_EQ(true, reflection->ContainsMapKey(
                           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);
       EXPECT_EQ(true, reflection->ContainsMapKey(
                           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);
       EXPECT_EQ(true, reflection->ContainsMapKey(
                           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);
       EXPECT_EQ(true, reflection->ContainsMapKey(
                           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);
       EXPECT_EQ(true, reflection->ContainsMapKey(
                           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);
       EXPECT_EQ(true, reflection->ContainsMapKey(
                           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);
       EXPECT_EQ(true, reflection->ContainsMapKey(message, F("map_int32_float"),
                                                  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);
       EXPECT_EQ(true, reflection->ContainsMapKey(message, F("map_int32_double"),
                                                  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);
       EXPECT_EQ(true, reflection->ContainsMapKey(message, F("map_bool_bool"),
                                                  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);
       EXPECT_EQ(true, reflection->ContainsMapKey(
                           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);
       EXPECT_EQ(true, reflection->ContainsMapKey(message, F("map_int32_bytes"),
                                                  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);
       EXPECT_EQ(true, reflection->ContainsMapKey(message, F("map_int32_enum"),
                                                  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);
       EXPECT_EQ(true, reflection->ContainsMapKey(
                           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);
     }
   }
 }

+ 12 - 2
src/google/protobuf/message.h

@@ -145,6 +145,7 @@ class MessageFactory;
 class AssignDescriptorsHelper;
 class DynamicMessageFactory;
 class MapKey;
+class MapValueConstRef;
 class MapValueRef;
 class MapIterator;
 class MapReflectionTester;
@@ -758,7 +759,7 @@ class PROTOBUF_EXPORT Reflection final {
       Message* message, const FieldDescriptor* field) const;
 
   // 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.
   //
   // 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
   // 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,
                               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
   // otherwise.
   bool DeleteMapValue(Message* message, const FieldDescriptor* field,

+ 1 - 1
src/google/protobuf/parse_context.cc

@@ -180,7 +180,7 @@ std::pair<const char*, bool> EpsCopyInputStream::DoneFallback(const char* ptr,
       if (PROTOBUF_PREDICT_FALSE(overrun != 0)) return {nullptr, true};
       GOOGLE_DCHECK(limit_ > 0);
       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();
       return {ptr, true};
     }

+ 4 - 4
src/google/protobuf/port_def.inc

@@ -300,14 +300,14 @@
 
 // Shared google3/opensource definitions. //////////////////////////////////////
 
-#define PROTOBUF_VERSION 3012003
-#define PROTOBUF_MIN_HEADER_VERSION_FOR_PROTOC 3012000
-#define PROTOBUF_MIN_PROTOC_VERSION 3012000
+#define PROTOBUF_VERSION 3013000
+#define PROTOBUF_MIN_HEADER_VERSION_FOR_PROTOC 3013000
+#define PROTOBUF_MIN_PROTOC_VERSION 3013000
 #define PROTOBUF_VERSION_SUFFIX ""
 
 // The minimum library version which works with the current version of the
 // 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
 #define PROTOBUF_RTTI 0

+ 2 - 2
src/google/protobuf/source_context.pb.h

@@ -8,12 +8,12 @@
 #include <string>
 
 #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 incompatible with your Protocol Buffer headers. Please update
 #error your headers.
 #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 incompatible with your Protocol Buffer headers. Please
 #error regenerate this file with a newer version of protoc.

+ 2 - 2
src/google/protobuf/struct.pb.h

@@ -8,12 +8,12 @@
 #include <string>
 
 #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 incompatible with your Protocol Buffer headers. Please update
 #error your headers.
 #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 incompatible with your Protocol Buffer headers. Please
 #error regenerate this file with a newer version of protoc.

+ 1 - 1
src/google/protobuf/stubs/casts.h

@@ -47,7 +47,7 @@ namespace internal {
 // When you use implicit_cast, the compiler checks that the cast is safe.
 // Such explicit implicit_casts are necessary in surprisingly many
 // 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
 // implicit_cast is the same as for static_cast etc.:

+ 1 - 1
src/google/protobuf/stubs/common.cc

@@ -304,7 +304,7 @@ void DoNothing() {}
 //
 // TODO(xiaofeng): PROTOBUF_LITTLE_ENDIAN is unfortunately defined in
 // 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) {
   union {
     uint32 result;

+ 4 - 4
src/google/protobuf/stubs/common.h

@@ -82,7 +82,7 @@ namespace internal {
 
 // The current version, represented as a single integer to make comparison
 // 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.
 #define GOOGLE_PROTOBUF_VERSION_SUFFIX ""
@@ -90,15 +90,15 @@ namespace internal {
 // The minimum header version which works with the current version of
 // the library.  This constant should only be used by protoc's C++ code
 // generator.
-static const int kMinHeaderVersionForLibrary = 3012000;
+static const int kMinHeaderVersionForLibrary = 3013000;
 
 // The minimum protoc version which works with the current version of the
 // 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
 // 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
 // below to call this.

+ 1 - 1
src/google/protobuf/stubs/time_test.cc

@@ -38,7 +38,7 @@ namespace internal {
 namespace {
 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.
 int64 CreateTimestamp(int year, int month, int day) {
   DateTime time;

+ 2 - 2
src/google/protobuf/text_format_unittest.cc

@@ -718,7 +718,7 @@ TEST_F(TextFormatTest, CompactRepeatedFieldPrinter) {
       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.
 class MultilineStringPrinter : public TextFormat::FastFieldValuePrinter {
  public:
@@ -2055,7 +2055,7 @@ TEST(TextFormatUnknownFieldTest, TestUnknownField) {
                              "  }\n"
                              ">",
                              &proto));
-  // Unmatched delimeters for message body
+  // Unmatched delimiters for message body
   EXPECT_FALSE(parser.ParseFromString("unknown_message: {>", &proto));
   // Unknown extension
   EXPECT_TRUE(

+ 2 - 2
src/google/protobuf/timestamp.pb.h

@@ -8,12 +8,12 @@
 #include <string>
 
 #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 incompatible with your Protocol Buffer headers. Please update
 #error your headers.
 #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 incompatible with your Protocol Buffer headers. Please
 #error regenerate this file with a newer version of protoc.

+ 2 - 2
src/google/protobuf/type.pb.h

@@ -8,12 +8,12 @@
 #include <string>
 
 #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 incompatible with your Protocol Buffer headers. Please update
 #error your headers.
 #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 incompatible with your Protocol Buffer headers. Please
 #error regenerate this file with a newer version of protoc.

+ 3 - 3
src/google/protobuf/util/field_mask_util.cc

@@ -199,7 +199,7 @@ class FieldMaskTree {
 
   // Remove a path from the tree.
   // 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
   // will be moved.
   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) {
     if (!new_branch && node != &root_ && node->children.empty()) {
       // 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").
       return;
     }
@@ -707,7 +707,7 @@ bool FieldMaskUtil::TrimMessage(const FieldMask& mask, Message* message,
   // fields.
   FieldMaskTree tree;
   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.
   if (options.keep_required_fields()) {
     tree.AddRequiredFieldPath(GOOGLE_CHECK_NOTNULL(message->GetDescriptor()));

+ 1 - 1
src/google/protobuf/util/internal/constants.h

@@ -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".
 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;
 
 // Maximum seconds allowed in a google.protobuf.Timestamp value.

+ 1 - 1
src/google/protobuf/util/internal/json_objectwriter.h

@@ -152,7 +152,7 @@ class PROTOBUF_EXPORT JsonObjectWriter : public StructuredObjectWriter {
       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()).
     bool is_json_object() const { return is_json_object_; }
 

+ 1 - 1
src/google/protobuf/util/internal/json_stream_parser_test.cc

@@ -146,7 +146,7 @@ class JsonStreamParserTest : public ::testing::Test {
 
 #ifndef _MSC_VER
   // 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.
   ::testing::InSequence in_sequence_;
 #endif  // !_MSC_VER

+ 1 - 1
src/google/protobuf/util/internal/type_info_test_helper.h

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

+ 2 - 2
src/google/protobuf/util/internal/utility.h

@@ -82,8 +82,8 @@ PROTOBUF_EXPORT std::string GetStringOptionOrDefault(
 
 // Returns a boolean value contained in Any type.
 // 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
-// can use.
+// add more error checking and move to a more public/shareable location so
+// others can use.
 PROTOBUF_EXPORT bool GetBoolFromAny(const google::protobuf::Any& any);
 
 // Returns int64 value contained in Any type.

+ 28 - 27
src/google/protobuf/util/message_differencer.cc

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

+ 1 - 1
src/google/protobuf/util/message_differencer.h

@@ -318,7 +318,7 @@ class PROTOBUF_EXPORT MessageDifferencer {
 
   // Abstract base class from which all IgnoreCriteria derive.
   // 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
   // true or all return false.
   // IsIgnored is called for fields where at least one side has a value.

+ 7 - 7
src/google/protobuf/wire_format.cc

@@ -67,7 +67,7 @@ namespace internal {
 static size_t MapKeyDataOnlyByteSize(const FieldDescriptor* field,
                                      const MapKey& value);
 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(
-    const FieldDescriptor* field, const MapValueRef& value, uint8* target,
+    const FieldDescriptor* field, const MapValueConstRef& value, uint8* target,
     io::EpsCopyOutputStream* stream) {
   target = stream->EnsureSpace(target);
   switch (field->type()) {
@@ -1184,7 +1184,8 @@ class MapKeySorter {
 
 static uint8* InternalSerializeMapEntry(const FieldDescriptor* field,
                                         const MapKey& key,
-                                        const MapValueRef& value, uint8* target,
+                                        const MapValueConstRef& value,
+                                        uint8* target,
                                         io::EpsCopyOutputStream* stream) {
   const FieldDescriptor* key_field = field->message_type()->field(0);
   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);
         for (std::vector<MapKey>::iterator it = sorted_key_list.begin();
              it != sorted_key_list.end(); ++it) {
-          MapValueRef map_value;
-          message_reflection->InsertOrLookupMapValue(
-              const_cast<Message*>(&message), field, *it, &map_value);
+          MapValueConstRef map_value;
+          message_reflection->LookupMapValue(message, field, *it, &map_value);
           target =
               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,
-                                          const MapValueRef& value) {
+                                          const MapValueConstRef& value) {
   switch (field->type()) {
     case FieldDescriptor::TYPE_GROUP:
       GOOGLE_LOG(FATAL) << "Unsupported";

+ 2 - 2
src/google/protobuf/wrappers.pb.h

@@ -8,12 +8,12 @@
 #include <string>
 
 #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 incompatible with your Protocol Buffer headers. Please update
 #error your headers.
 #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 incompatible with your Protocol Buffer headers. Please
 #error regenerate this file with a newer version of protoc.

+ 17 - 2
update_version.py

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