Forráskód Böngészése

Sync from Piper @365872496

PROTOBUF_SYNC_PIPER
Joshua Haberman 4 éve
szülő
commit
4a6dc34d3a
72 módosított fájl, 956 hozzáadás és 517 törlés
  1. 24 1
      CHANGES.txt
  2. 1 1
      Protobuf-C++.podspec
  3. 5 0
      cmake/CMakeLists.txt
  4. 3 1
      cmake/install.cmake
  5. 3 3
      cmake/protobuf-config.cmake.in
  6. 14 1
      configure.ac
  7. 2 2
      conformance/conformance_cpp.cc
  8. 1 0
      java/core/BUILD
  9. 19 3
      java/core/src/main/java/com/google/protobuf/CodedInputStream.java
  10. 1 1
      java/core/src/main/java/com/google/protobuf/InvalidProtocolBufferException.java
  11. 41 8
      java/core/src/test/java/com/google/protobuf/CodedInputStreamTest.java
  12. 1 0
      java/lite/pom.xml
  13. 7 6
      java/util/src/main/java/com/google/protobuf/util/Durations.java
  14. 1 1
      js/package.json
  15. 22 0
      kokoro/release/python/linux/build_artifacts.sh
  16. 51 6
      kokoro/release/python/linux/config.sh
  17. 1 1
      python/google/protobuf/__init__.py
  18. 1 8
      python/google/protobuf/internal/message_test.py
  19. 0 6
      python/google/protobuf/internal/python_message.py
  20. 2 1
      python/google/protobuf/pyext/descriptor.cc
  21. 3 2
      python/google/protobuf/pyext/descriptor_pool.cc
  22. 6 4
      python/google/protobuf/pyext/map_container.cc
  23. 14 15
      python/google/protobuf/pyext/message.cc
  24. 1 1
      python/google/protobuf/pyext/message.h
  25. 3 2
      python/google/protobuf/pyext/message_factory.cc
  26. 2 2
      src/Makefile.am
  27. 2 2
      src/google/protobuf/any.pb.h
  28. 4 4
      src/google/protobuf/api.pb.h
  29. 23 3
      src/google/protobuf/compiler/command_line_interface.cc
  30. 3 0
      src/google/protobuf/compiler/command_line_interface.h
  31. 31 2
      src/google/protobuf/compiler/command_line_interface_unittest.cc
  32. 2 2
      src/google/protobuf/compiler/cpp/cpp_file.cc
  33. 1 1
      src/google/protobuf/compiler/cpp/cpp_message.cc
  34. 5 5
      src/google/protobuf/compiler/plugin.pb.h
  35. 28 28
      src/google/protobuf/descriptor.pb.h
  36. 2 2
      src/google/protobuf/duration.pb.h
  37. 2 2
      src/google/protobuf/empty.pb.h
  38. 2 2
      src/google/protobuf/field_mask.pb.h
  39. 2 0
      src/google/protobuf/io/coded_stream.h
  40. 0 1
      src/google/protobuf/parse_context.h
  41. 0 7
      src/google/protobuf/port.h
  42. 1 1
      src/google/protobuf/port_def.inc
  43. 2 2
      src/google/protobuf/source_context.pb.h
  44. 4 4
      src/google/protobuf/struct.pb.h
  45. 1 1
      src/google/protobuf/stubs/common.h
  46. 1 3
      src/google/protobuf/stubs/logging.h
  47. 2 0
      src/google/protobuf/stubs/port.h
  48. 159 31
      src/google/protobuf/stubs/status.cc
  49. 113 42
      src/google/protobuf/stubs/status.h
  50. 173 33
      src/google/protobuf/stubs/status_test.cc
  51. 11 14
      src/google/protobuf/stubs/statusor.h
  52. 18 18
      src/google/protobuf/stubs/statusor_test.cc
  53. 0 43
      src/google/protobuf/stubs/stringpiece.h
  54. 0 3
      src/google/protobuf/stubs/strutil.h
  55. 2 2
      src/google/protobuf/timestamp.pb.h
  56. 6 6
      src/google/protobuf/type.pb.h
  57. 4 4
      src/google/protobuf/util/field_comparator.h
  58. 16 20
      src/google/protobuf/util/internal/datapiece.cc
  59. 3 5
      src/google/protobuf/util/internal/datapiece.h
  60. 12 21
      src/google/protobuf/util/internal/field_mask_utility.cc
  61. 16 21
      src/google/protobuf/util/internal/json_stream_parser.cc
  62. 1 1
      src/google/protobuf/util/internal/json_stream_parser.h
  63. 4 4
      src/google/protobuf/util/internal/json_stream_parser_test.cc
  64. 1 4
      src/google/protobuf/util/internal/proto_writer.cc
  65. 16 32
      src/google/protobuf/util/internal/protostream_objectsource.cc
  66. 1 1
      src/google/protobuf/util/internal/protostream_objectsource.h
  67. 8 8
      src/google/protobuf/util/internal/protostream_objectsource_test.cc
  68. 22 25
      src/google/protobuf/util/internal/protostream_objectwriter.cc
  69. 7 10
      src/google/protobuf/util/json_util.cc
  70. 1 2
      src/google/protobuf/util/json_util_test.cc
  71. 5 9
      src/google/protobuf/util/type_resolver_util.cc
  72. 10 10
      src/google/protobuf/wrappers.pb.h

+ 24 - 1
CHANGES.txt

@@ -9,9 +9,32 @@ Unreleased Changes (C++/Java/Python/PHP/Objective-C/C#/Ruby/JavaScript)
   * For iterator-pair function parameter types, take both iterators by value.
   * Code-space savings and perhaps some modest performance improvements in
     RepeatedPtrField.
+  * Eliminate nullptr check from every tag parse.
+  * Remove unused _$name$_cached_byte_size_ fields.
+  * Serialize extension ranges together when not broken by a proto field in the
+    middle.
+  * Do out-of-line allocation and deallocation of string object in ArenaString.
+  * Streamline ParseContext::ParseMessage<T> to avoid code bloat and improve
+    performance.
+  * New member functions RepeatedField::Assign, RepeatedPtrField::{Add, Assign}.
+  * Fix undefined behavior warning due to innocuous uninitialization of value
+    on an error path.
+  * Avoid expensive inlined code space for encoding message length for messages
+    >= 128 bytes and instead do a procedure call to a shared out-of-line routine.
 
   Java:
-  * Exceptions thrown while reading from an InputStream in parseFrom are now included as causes.
+  * Exceptions thrown while reading from an InputStream in parseFrom are now
+    included as causes.
+  * Support potentially more efficient proto parsing from RopeByteStrings.
+  * Clarify runtime of ByteString.Output.toStringBuffer().
+
+  Python
+  * Fixed a bug in text format where a trailing colon was printed for repeated field.
+  * When TextFormat encounters a duplicate message map key, replace the current
+    one instead of merging.
+
+  JavaScript
+  * Make Any.pack() chainable.
 
 2021-03-10 version 3.15.6 (C++/Java/Python/PHP/Objective-C/C#/Ruby/JavaScript)
 

+ 1 - 1
Protobuf-C++.podspec

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

+ 5 - 0
cmake/CMakeLists.txt

@@ -45,6 +45,7 @@ option(protobuf_BUILD_CONFORMANCE "Build conformance tests" OFF)
 option(protobuf_BUILD_EXAMPLES "Build examples" OFF)
 option(protobuf_BUILD_PROTOC_BINARIES "Build libprotoc and protoc compiler" ON)
 option(protobuf_BUILD_LIBPROTOC "Build libprotoc" OFF)
+option(protobuf_DISABLE_RTTI "Remove runtime type information in the binaries" OFF)
 if (BUILD_SHARED_LIBS)
   set(protobuf_BUILD_SHARED_LIBS_DEFAULT ON)
 else (BUILD_SHARED_LIBS)
@@ -117,6 +118,10 @@ endif()
 
 add_definitions(-DGOOGLE_PROTOBUF_CMAKE_BUILD)
 
+if (protobuf_DISABLE_RTTI)
+  add_definitions(-DGOOGLE_PROTOBUF_NO_RTTI=1)
+endif()
+
 find_package(Threads REQUIRED)
 if (CMAKE_USE_PTHREADS_INIT)
   add_definitions(-DHAVE_PTHREAD)

+ 3 - 1
cmake/install.cmake

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

+ 3 - 3
cmake/protobuf-config.cmake.in

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

+ 14 - 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.15.2],[protobuf@googlegroups.com],[protobuf])
+AC_INIT([Protocol Buffers],[3.15.6],[protobuf@googlegroups.com],[protobuf])
 
 AM_MAINTAINER_MODE([enable])
 
@@ -223,6 +223,19 @@ case "$target_os" in
 esac
 AM_CONDITIONAL([OBJC_CONFORMANCE_TEST], [test $OBJC_CONFORMANCE_TEST = 1])
 
+AC_MSG_CHECKING(whether -llog is needed)
+ANDROID_TEST=no
+case "$target_os" in
+  *android*)
+    ANDROID_TEST=yes
+    ;;
+esac
+AC_MSG_RESULT($ANDROID_TEST)
+if test "x$ANDROID_TEST" = xyes; then
+  LIBLOG_LIBS="-llog"
+fi
+AC_SUBST([LIBLOG_LIBS])
+
 # HACK:  Make gmock's configure script pick up our copy of CFLAGS and CXXFLAGS,
 #   since the flags added by ACX_CHECK_SUNCC must be used when compiling gmock
 #   too.

+ 2 - 2
conformance/conformance_cpp.cc

@@ -134,7 +134,7 @@ void DoTest(const ConformanceRequest& request, ConformanceResponse* response) {
                              &proto_binary, options);
       if (!status.ok()) {
         response->set_parse_error(string("Parse error: ") +
-                                  std::string(status.error_message()));
+                                  std::string(status.message()));
         return;
       }
 
@@ -189,7 +189,7 @@ void DoTest(const ConformanceRequest& request, ConformanceResponse* response) {
       if (!status.ok()) {
         response->set_serialize_error(
             string("Failed to serialize JSON output: ") +
-            std::string(status.error_message()));
+            std::string(status.message()));
         return;
       }
       break;

+ 1 - 0
java/core/BUILD

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

+ 19 - 3
java/core/src/main/java/com/google/protobuf/CodedInputStream.java

@@ -3523,9 +3523,25 @@ public abstract class CodedInputStream {
           return ByteString.wrap(bytes);
         }
       } else if (size > 0 && size <= remaining()) {
-        byte[] temp = new byte[size];
-        readRawBytesTo(temp, 0, size);
-        return ByteString.wrap(temp);
+        if (immutable && enableAliasing) {
+          ArrayList<ByteString> byteStrings = new ArrayList<>();
+          int l = size;
+          while (l > 0) {
+            if (currentRemaining() == 0) {
+              getNextByteBuffer();
+            }
+            int bytesToCopy = Math.min(l, (int) currentRemaining());
+            int idx = (int) (currentByteBufferPos - currentAddress);
+            byteStrings.add(ByteString.wrap(slice(idx, idx + bytesToCopy)));
+            l -= bytesToCopy;
+            currentByteBufferPos += bytesToCopy;
+          }
+          return ByteString.copyFrom(byteStrings);
+        } else {
+          byte[] temp = new byte[size];
+          readRawBytesTo(temp, 0, size);
+          return ByteString.wrap(temp);
+        }
       }
 
       if (size == 0) {

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

@@ -78,7 +78,7 @@ public class InvalidProtocolBufferException extends IOException {
     /* This write can be racy if the same exception is stored and then thrown by multiple custom
      * InputStreams on different threads. But since it only ever moves from false->true, there's no
      * problem. A thread checking this condition after catching this exception from a delegate
-     * stram of CodedInputStream is guaranteed to always observe true, because a write on the same
+     * stream of CodedInputStream is guaranteed to always observe true, because a write on the same
      * thread set the value when the exception left the delegate. A thread checking the same
      * condition with an exception created by CodedInputStream is guaranteed to always see false,
      * because the exception has not been exposed to any code that could publish it to other threads

+ 41 - 8
java/core/src/test/java/com/google/protobuf/CodedInputStreamTest.java

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

+ 1 - 0
java/lite/pom.xml

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

+ 7 - 6
java/util/src/main/java/com/google/protobuf/util/Durations.java

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

+ 1 - 1
js/package.json

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

+ 22 - 0
kokoro/release/python/linux/build_artifacts.sh

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

+ 51 - 6
kokoro/release/python/linux/config.sh

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

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

@@ -30,4 +30,4 @@
 
 # Copyright 2007 Google Inc. All Rights Reserved.
 
-__version__ = '3.15.2'
+__version__ = '3.15.6'

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

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

+ 0 - 6
python/google/protobuf/internal/python_message.py

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

+ 2 - 1
python/google/protobuf/pyext/descriptor.cc

@@ -250,8 +250,9 @@ static PyObject* GetOrBuildOptions(const DescriptorClass *descriptor) {
                  message_type->full_name().c_str());
     return NULL;
   }
+  ScopedPyObjectPtr args(PyTuple_New(0));
   ScopedPyObjectPtr value(
-      PyEval_CallObject(message_class->AsPyObject(), NULL));
+      PyObject_Call(message_class->AsPyObject(), args.get(), NULL));
   Py_DECREF(message_class);
   if (value == NULL) {
     return NULL;

+ 3 - 2
python/google/protobuf/pyext/descriptor_pool.cc

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

+ 6 - 4
python/google/protobuf/pyext/map_container.cc

@@ -463,10 +463,11 @@ int MapReflectionFriend::ScalarMapSetItem(PyObject* _self, PyObject* key,
 
 static PyObject* ScalarMapGet(PyObject* self, PyObject* args,
                               PyObject* kwargs) {
-  static char* kwlist[] = {"key", "default", nullptr};
+  static const char* kwlist[] = {"key", "default", nullptr};
   PyObject* key;
   PyObject* default_value = NULL;
-  if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O", kwlist, &key,
+  if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O",
+                                   const_cast<char**>(kwlist), &key,
                                    &default_value)) {
     return NULL;
   }
@@ -758,10 +759,11 @@ PyObject* MapReflectionFriend::MessageMapToStr(PyObject* _self) {
 }
 
 PyObject* MessageMapGet(PyObject* self, PyObject* args, PyObject* kwargs) {
-  static char* kwlist[] = {"key", "default", nullptr};
+  static const char* kwlist[] = {"key", "default", nullptr};
   PyObject* key;
   PyObject* default_value = NULL;
-  if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O", kwlist, &key,
+  if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O",
+                                   const_cast<char**>(kwlist), &key,
                                    &default_value)) {
     return NULL;
   }

+ 14 - 15
python/google/protobuf/pyext/message.cc

@@ -197,15 +197,14 @@ static int AddDescriptors(PyObject* cls, const Descriptor* descriptor) {
 }
 
 static PyObject* New(PyTypeObject* type, PyObject* args, PyObject* kwargs) {
-  static char *kwlist[] = {"name", "bases", "dict", 0};
+  static const char* kwlist[] = {"name", "bases", "dict", 0};
   PyObject *bases, *dict;
   const char* name;
 
   // Check arguments: (name, bases, dict)
-  if (!PyArg_ParseTupleAndKeywords(args, kwargs, "sO!O!:type", kwlist,
-                                   &name,
-                                   &PyTuple_Type, &bases,
-                                   &PyDict_Type, &dict)) {
+  if (!PyArg_ParseTupleAndKeywords(
+          args, kwargs, "sO!O!:type", const_cast<char**>(kwlist), &name,
+          &PyTuple_Type, &bases, &PyDict_Type, &dict)) {
     return NULL;
   }
 
@@ -547,7 +546,7 @@ PyObject* PickleError_class;
 
 // Format an error message for unexpected types.
 // Always return with an exception set.
-void FormatTypeError(PyObject* arg, char* expected_types) {
+void FormatTypeError(PyObject* arg, const char* expected_types) {
   // This function is often called with an exception set.
   // Clear it to call PyObject_Repr() in good conditions.
   PyErr_Clear();
@@ -1680,10 +1679,10 @@ static PyObject* InternalSerializeToString(
     CMessage* self, PyObject* args, PyObject* kwargs,
     bool require_initialized) {
   // Parse the "deterministic" kwarg; defaults to False.
-  static char* kwlist[] = { "deterministic", 0 };
+  static const char* kwlist[] = {"deterministic", 0};
   PyObject* deterministic_obj = Py_None;
-  if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O", kwlist,
-                                   &deterministic_obj)) {
+  if (!PyArg_ParseTupleAndKeywords(
+          args, kwargs, "|O", const_cast<char**>(kwlist), &deterministic_obj)) {
     return NULL;
   }
   // Preemptively convert to a bool first, so we don't need to back out of
@@ -1928,9 +1927,8 @@ PyObject* SetAllowOversizeProtos(PyObject* m, PyObject* arg) {
 }
 
 static PyObject* MergeFromString(CMessage* self, PyObject* arg) {
-  const void* data;
-  Py_ssize_t data_length;
-  if (PyObject_AsReadBuffer(arg, &data, &data_length) < 0) {
+  Py_buffer data;
+  if (PyObject_GetBuffer(arg, &data, PyBUF_SIMPLE) < 0) {
     return NULL;
   }
 
@@ -1943,7 +1941,8 @@ static PyObject* MergeFromString(CMessage* self, PyObject* arg) {
   const char* ptr;
   internal::ParseContext ctx(
       depth, false, &ptr,
-      StringPiece(static_cast<const char*>(data), data_length));
+      StringPiece(static_cast<const char*>(data.buf), data.len));
+  PyBuffer_Release(&data);
   ctx.data().pool = factory->pool->pool;
   ctx.data().factory = factory->message_factory;
 
@@ -1969,9 +1968,9 @@ static PyObject* MergeFromString(CMessage* self, PyObject* arg) {
     // TODO(jieluo): Raise error and return NULL instead.
     // b/27494216
     PyErr_Warn(nullptr, "Unexpected end-group tag: Not all data was converted");
-    return PyInt_FromLong(data_length - ctx.BytesUntilLimit(ptr));
+    return PyInt_FromLong(data.len - ctx.BytesUntilLimit(ptr));
   }
-  return PyInt_FromLong(data_length);
+  return PyInt_FromLong(data.len);
 }
 
 static PyObject* ParseFromString(CMessage* self, PyObject* arg) {

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

@@ -330,7 +330,7 @@ PyObject* SetAllowOversizeProtos(PyObject* m, PyObject* arg);
 
 #define FULL_MODULE_NAME "google.protobuf.pyext._message"
 
-void FormatTypeError(PyObject* arg, char* expected_types);
+void FormatTypeError(PyObject* arg, const char* expected_types);
 template<class T>
 bool CheckAndGetInteger(PyObject* arg, T* value);
 bool CheckAndGetDouble(PyObject* arg, double* value);

+ 3 - 2
python/google/protobuf/pyext/message_factory.cc

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

+ 2 - 2
src/Makefile.am

@@ -18,7 +18,7 @@ else
 PTHREAD_DEF =
 endif
 
-PROTOBUF_VERSION = 26:2:0
+PROTOBUF_VERSION = 26:6:0
 
 if GCC
 # Turn on all warnings except for sign comparison (we ignore sign comparison
@@ -30,7 +30,7 @@ endif
 
 AM_CXXFLAGS = $(NO_OPT_CXXFLAGS) $(PROTOBUF_OPT_FLAG)
 
-AM_LDFLAGS = $(PTHREAD_CFLAGS)
+AM_LDFLAGS = $(PTHREAD_CFLAGS) ${LIBLOG_LIBS}
 
 # If I say "dist_include_DATA", automake complains that $(includedir) is not
 # a "legitimate" directory for DATA.  Screw you, automake.

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

@@ -13,7 +13,7 @@
 #error incompatible with your Protocol Buffer headers. Please update
 #error your headers.
 #endif
-#if 3015002 < PROTOBUF_MIN_PROTOC_VERSION
+#if 3015006 < 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.
@@ -69,7 +69,7 @@ class PROTOBUF_EXPORT Any PROTOBUF_FINAL :
     public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.Any) */ {
  public:
   inline Any() : Any(nullptr) {}
-  virtual ~Any();
+  ~Any() override;
   explicit constexpr Any(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);
 
   Any(const Any& from);

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

@@ -13,7 +13,7 @@
 #error incompatible with your Protocol Buffer headers. Please update
 #error your headers.
 #endif
-#if 3015002 < PROTOBUF_MIN_PROTOC_VERSION
+#if 3015006 < 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.
@@ -79,7 +79,7 @@ class PROTOBUF_EXPORT Api PROTOBUF_FINAL :
     public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.Api) */ {
  public:
   inline Api() : Api(nullptr) {}
-  virtual ~Api();
+  ~Api() override;
   explicit constexpr Api(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);
 
   Api(const Api& from);
@@ -322,7 +322,7 @@ class PROTOBUF_EXPORT Method PROTOBUF_FINAL :
     public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.Method) */ {
  public:
   inline Method() : Method(nullptr) {}
-  virtual ~Method();
+  ~Method() override;
   explicit constexpr Method(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);
 
   Method(const Method& from);
@@ -543,7 +543,7 @@ class PROTOBUF_EXPORT Mixin PROTOBUF_FINAL :
     public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.Mixin) */ {
  public:
   inline Mixin() : Mixin(nullptr) {}
-  virtual ~Mixin();
+  ~Mixin() override;
   explicit constexpr Mixin(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);
 
   Mixin(const Mixin& from);

+ 23 - 3
src/google/protobuf/compiler/command_line_interface.cc

@@ -290,7 +290,10 @@ class CommandLineInterface::ErrorPrinter
       public DescriptorPool::ErrorCollector {
  public:
   ErrorPrinter(ErrorFormat format, DiskSourceTree* tree = NULL)
-      : format_(format), tree_(tree), found_errors_(false) {}
+      : format_(format),
+        tree_(tree),
+        found_errors_(false),
+        found_warnings_(false) {}
   ~ErrorPrinter() {}
 
   // implements MultiFileErrorCollector ------------------------------
@@ -302,6 +305,7 @@ class CommandLineInterface::ErrorPrinter
 
   void AddWarning(const std::string& filename, int line, int column,
                   const std::string& message) {
+    found_warnings_ = true;
     AddErrorOrWarning(filename, line, column, message, "warning", std::clog);
   }
 
@@ -329,6 +333,8 @@ class CommandLineInterface::ErrorPrinter
 
   bool FoundErrors() const { return found_errors_; }
 
+  bool FoundWarnings() const { return found_warnings_; }
+
  private:
   void AddErrorOrWarning(const std::string& filename, int line, int column,
                          const std::string& message, const std::string& type,
@@ -367,6 +373,7 @@ class CommandLineInterface::ErrorPrinter
   const ErrorFormat format_;
   DiskSourceTree* tree_;
   bool found_errors_;
+  bool found_warnings_;
 };
 
 // -------------------------------------------------------------------
@@ -584,10 +591,12 @@ bool CommandLineInterface::GeneratorContextImpl::WriteAllToZip(
 
   if (stream.GetErrno() != 0) {
     std::cerr << filename << ": " << strerror(stream.GetErrno()) << std::endl;
+    return false;
   }
 
   if (!stream.Close()) {
     std::cerr << filename << ": " << strerror(stream.GetErrno()) << std::endl;
+    return false;
   }
 
   return true;
@@ -1119,7 +1128,8 @@ int CommandLineInterface::Run(int argc, const char* const argv[]) {
     }
   }
 
-  if (error_collector->FoundErrors()) {
+  if (error_collector->FoundErrors() ||
+      (fatal_warnings_ && error_collector->FoundWarnings())) {
     return 1;
   }
 
@@ -1632,7 +1642,7 @@ bool CommandLineInterface::ParseArgument(const char* arg, std::string* name,
       *name == "--version" || *name == "--decode_raw" ||
       *name == "--print_free_field_numbers" ||
       *name == "--experimental_allow_proto3_optional" ||
-      *name == "--deterministic_output") {
+      *name == "--deterministic_output" || *name == "--fatal_warnings") {
     // HACK:  These are the only flags that don't take a value.
     //   They probably should not be hard-coded like this but for now it's
     //   not worth doing better.
@@ -1885,6 +1895,12 @@ CommandLineInterface::InterpretArgument(const std::string& name,
       return PARSE_ARGUMENT_FAIL;
     }
 
+  } else if (name == "--fatal_warnings") {
+    if (fatal_warnings_) {
+      std::cerr << name << " may only be passed once." << std::endl;
+      return PARSE_ARGUMENT_FAIL;
+    }
+    fatal_warnings_ = true;
   } else if (name == "--plugin") {
     if (plugin_prefix_.empty()) {
       std::cerr << "This compiler does not support plugins." << std::endl;
@@ -2044,6 +2060,10 @@ Parse PROTO_FILES and generate output based on the options given:
   --error_format=FORMAT       Set the format in which to print errors.
                               FORMAT may be 'gcc' (the default) or 'msvs'
                               (Microsoft Visual Studio format).
+  --fatal_warnings            Make warnings be fatal (similar to -Werr in
+                              gcc). This flag will make protoc return
+                              with a non-zero exit code if any warnings
+                              are generated.
   --print_free_field_numbers  Print the free field numbers of the messages
                               defined in the given proto files. Groups share
                               the same field number space with the parent

+ 3 - 0
src/google/protobuf/compiler/command_line_interface.h

@@ -393,6 +393,9 @@ class PROTOC_EXPORT CommandLineInterface {
 
   ErrorFormat error_format_ = ERROR_FORMAT_GCC;
 
+  // True if we should treat warnings as errors that fail the compilation.
+  bool fatal_warnings_ = false;
+
   std::vector<std::pair<std::string, std::string> >
       proto_path_;                        // Search path for proto files.
   std::vector<std::string> input_files_;  // Names of the input proto files.

+ 31 - 2
src/google/protobuf/compiler/command_line_interface_unittest.cc

@@ -159,6 +159,11 @@ class CommandLineInterfaceTest : public testing::Test {
   void ExpectCapturedStdoutSubstringWithZeroReturnCode(
       const std::string& expected_substring);
 
+  // Checks that Run() returned zero and the stderr contains the given
+  // substring.
+  void ExpectCapturedStderrSubstringWithZeroReturnCode(
+      const std::string& expected_substring);
+
 #if defined(_WIN32) && !defined(__CYGWIN__)
   // Returns true if ExpectErrorSubstring(expected_substring) would pass, but
   // does not fail otherwise.
@@ -428,8 +433,8 @@ void CommandLineInterfaceTest::ExpectErrorSubstring(
 
 void CommandLineInterfaceTest::ExpectWarningSubstring(
     const std::string& expected_substring) {
-  EXPECT_EQ(0, return_code_);
   EXPECT_PRED_FORMAT2(testing::IsSubstring, expected_substring, error_text_);
+  EXPECT_EQ(0, return_code_);
 }
 
 #if defined(_WIN32) && !defined(__CYGWIN__)
@@ -517,6 +522,12 @@ void CommandLineInterfaceTest::ExpectCapturedStdoutSubstringWithZeroReturnCode(
                       captured_stdout_);
 }
 
+void CommandLineInterfaceTest::ExpectCapturedStderrSubstringWithZeroReturnCode(
+    const std::string& expected_substring) {
+  EXPECT_EQ(0, return_code_);
+  EXPECT_PRED_FORMAT2(testing::IsSubstring, expected_substring, error_text_);
+}
+
 void CommandLineInterfaceTest::ExpectFileContent(const std::string& filename,
                                                  const std::string& content) {
   std::string path = temp_directory_ + "/" + filename;
@@ -2305,7 +2316,7 @@ TEST_F(CommandLineInterfaceTest, MsvsFormatErrors) {
 }
 
 TEST_F(CommandLineInterfaceTest, InvalidErrorFormat) {
-  // Test --error_format=msvs
+  // Test invalid --error_format
 
   CreateTempFile("foo.proto",
                  "syntax = \"proto2\";\n"
@@ -2317,6 +2328,24 @@ TEST_F(CommandLineInterfaceTest, InvalidErrorFormat) {
   ExpectErrorText("Unknown error format: invalid\n");
 }
 
+TEST_F(CommandLineInterfaceTest, Warnings) {
+  // Test --fatal_warnings.
+
+  CreateTempFile("foo.proto",
+                 "syntax = \"proto2\";\n"
+                 "import \"bar.proto\";\n");
+  CreateTempFile("bar.proto", "syntax = \"proto2\";\n");
+
+  Run("protocol_compiler --test_out=$tmpdir "
+      "--proto_path=$tmpdir foo.proto");
+  ExpectCapturedStderrSubstringWithZeroReturnCode(
+      "foo.proto:2:1: warning: Import bar.proto is unused.");
+
+  Run("protocol_compiler --test_out=$tmpdir --fatal_warnings "
+      "--proto_path=$tmpdir foo.proto");
+  ExpectErrorSubstring("foo.proto:2:1: warning: Import bar.proto is unused.");
+}
+
 // -------------------------------------------------------------------
 // Flag parsing tests
 

+ 2 - 2
src/google/protobuf/compiler/cpp/cpp_file.cc

@@ -856,8 +856,8 @@ void FileGenerator::GenerateReflectionInitializationCode(io::Printer* printer) {
       "};\n"
       // This function exists to be marked as weak.
       // It can significantly speed up compilation by breaking up LLVM's SCC in
-      // the .pb.cc tranlation units. Large translation units see a reduction of
-      // more than 35% of walltime for optimized builds.
+      // the .pb.cc translation units. Large translation units see a reduction
+      // of more than 35% of walltime for optimized builds.
       // Without the weak attribute all the messages in the file, including all
       // the vtables and everything they use become part of the same SCC through
       // a cycle like:

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

@@ -1093,7 +1093,7 @@ void MessageGenerator::GenerateClassDefinition(io::Printer* printer) {
 
   format(
       "inline $classname$() : $classname$(nullptr) {}\n"
-      "virtual ~$classname$();\n"
+      "~$classname$() override;\n"
       "explicit constexpr "
       "$classname$(::$proto_ns$::internal::ConstantInitialized);\n"
       "\n"

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

@@ -13,7 +13,7 @@
 #error incompatible with your Protocol Buffer headers. Please update
 #error your headers.
 #endif
-#if 3015002 < PROTOBUF_MIN_PROTOC_VERSION
+#if 3015006 < 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.
@@ -115,7 +115,7 @@ class PROTOC_EXPORT Version PROTOBUF_FINAL :
     public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.compiler.Version) */ {
  public:
   inline Version() : Version(nullptr) {}
-  virtual ~Version();
+  ~Version() override;
   explicit constexpr Version(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);
 
   Version(const Version& from);
@@ -308,7 +308,7 @@ class PROTOC_EXPORT CodeGeneratorRequest PROTOBUF_FINAL :
     public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.compiler.CodeGeneratorRequest) */ {
  public:
   inline CodeGeneratorRequest() : CodeGeneratorRequest(nullptr) {}
-  virtual ~CodeGeneratorRequest();
+  ~CodeGeneratorRequest() override;
   explicit constexpr CodeGeneratorRequest(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);
 
   CodeGeneratorRequest(const CodeGeneratorRequest& from);
@@ -522,7 +522,7 @@ class PROTOC_EXPORT CodeGeneratorResponse_File PROTOBUF_FINAL :
     public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.compiler.CodeGeneratorResponse.File) */ {
  public:
   inline CodeGeneratorResponse_File() : CodeGeneratorResponse_File(nullptr) {}
-  virtual ~CodeGeneratorResponse_File();
+  ~CodeGeneratorResponse_File() override;
   explicit constexpr CodeGeneratorResponse_File(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);
 
   CodeGeneratorResponse_File(const CodeGeneratorResponse_File& from);
@@ -730,7 +730,7 @@ class PROTOC_EXPORT CodeGeneratorResponse PROTOBUF_FINAL :
     public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.compiler.CodeGeneratorResponse) */ {
  public:
   inline CodeGeneratorResponse() : CodeGeneratorResponse(nullptr) {}
-  virtual ~CodeGeneratorResponse();
+  ~CodeGeneratorResponse() override;
   explicit constexpr CodeGeneratorResponse(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);
 
   CodeGeneratorResponse(const CodeGeneratorResponse& from);

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

@@ -13,7 +13,7 @@
 #error incompatible with your Protocol Buffer headers. Please update
 #error your headers.
 #endif
-#if 3015002 < PROTOBUF_MIN_PROTOC_VERSION
+#if 3015006 < 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.
@@ -333,7 +333,7 @@ class PROTOBUF_EXPORT FileDescriptorSet PROTOBUF_FINAL :
     public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.FileDescriptorSet) */ {
  public:
   inline FileDescriptorSet() : FileDescriptorSet(nullptr) {}
-  virtual ~FileDescriptorSet();
+  ~FileDescriptorSet() override;
   explicit constexpr FileDescriptorSet(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);
 
   FileDescriptorSet(const FileDescriptorSet& from);
@@ -480,7 +480,7 @@ class PROTOBUF_EXPORT FileDescriptorProto PROTOBUF_FINAL :
     public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.FileDescriptorProto) */ {
  public:
   inline FileDescriptorProto() : FileDescriptorProto(nullptr) {}
-  virtual ~FileDescriptorProto();
+  ~FileDescriptorProto() override;
   explicit constexpr FileDescriptorProto(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);
 
   FileDescriptorProto(const FileDescriptorProto& from);
@@ -862,7 +862,7 @@ class PROTOBUF_EXPORT DescriptorProto_ExtensionRange PROTOBUF_FINAL :
     public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.DescriptorProto.ExtensionRange) */ {
  public:
   inline DescriptorProto_ExtensionRange() : DescriptorProto_ExtensionRange(nullptr) {}
-  virtual ~DescriptorProto_ExtensionRange();
+  ~DescriptorProto_ExtensionRange() override;
   explicit constexpr DescriptorProto_ExtensionRange(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);
 
   DescriptorProto_ExtensionRange(const DescriptorProto_ExtensionRange& from);
@@ -1040,7 +1040,7 @@ class PROTOBUF_EXPORT DescriptorProto_ReservedRange PROTOBUF_FINAL :
     public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.DescriptorProto.ReservedRange) */ {
  public:
   inline DescriptorProto_ReservedRange() : DescriptorProto_ReservedRange(nullptr) {}
-  virtual ~DescriptorProto_ReservedRange();
+  ~DescriptorProto_ReservedRange() override;
   explicit constexpr DescriptorProto_ReservedRange(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);
 
   DescriptorProto_ReservedRange(const DescriptorProto_ReservedRange& from);
@@ -1198,7 +1198,7 @@ class PROTOBUF_EXPORT DescriptorProto PROTOBUF_FINAL :
     public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.DescriptorProto) */ {
  public:
   inline DescriptorProto() : DescriptorProto(nullptr) {}
-  virtual ~DescriptorProto();
+  ~DescriptorProto() override;
   explicit constexpr DescriptorProto(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);
 
   DescriptorProto(const DescriptorProto& from);
@@ -1535,7 +1535,7 @@ class PROTOBUF_EXPORT ExtensionRangeOptions PROTOBUF_FINAL :
     public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.ExtensionRangeOptions) */ {
  public:
   inline ExtensionRangeOptions() : ExtensionRangeOptions(nullptr) {}
-  virtual ~ExtensionRangeOptions();
+  ~ExtensionRangeOptions() override;
   explicit constexpr ExtensionRangeOptions(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);
 
   ExtensionRangeOptions(const ExtensionRangeOptions& from);
@@ -1685,7 +1685,7 @@ class PROTOBUF_EXPORT FieldDescriptorProto PROTOBUF_FINAL :
     public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.FieldDescriptorProto) */ {
  public:
   inline FieldDescriptorProto() : FieldDescriptorProto(nullptr) {}
-  virtual ~FieldDescriptorProto();
+  ~FieldDescriptorProto() override;
   explicit constexpr FieldDescriptorProto(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);
 
   FieldDescriptorProto(const FieldDescriptorProto& from);
@@ -2102,7 +2102,7 @@ class PROTOBUF_EXPORT OneofDescriptorProto PROTOBUF_FINAL :
     public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.OneofDescriptorProto) */ {
  public:
   inline OneofDescriptorProto() : OneofDescriptorProto(nullptr) {}
-  virtual ~OneofDescriptorProto();
+  ~OneofDescriptorProto() override;
   explicit constexpr OneofDescriptorProto(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);
 
   OneofDescriptorProto(const OneofDescriptorProto& from);
@@ -2270,7 +2270,7 @@ class PROTOBUF_EXPORT EnumDescriptorProto_EnumReservedRange PROTOBUF_FINAL :
     public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.EnumDescriptorProto.EnumReservedRange) */ {
  public:
   inline EnumDescriptorProto_EnumReservedRange() : EnumDescriptorProto_EnumReservedRange(nullptr) {}
-  virtual ~EnumDescriptorProto_EnumReservedRange();
+  ~EnumDescriptorProto_EnumReservedRange() override;
   explicit constexpr EnumDescriptorProto_EnumReservedRange(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);
 
   EnumDescriptorProto_EnumReservedRange(const EnumDescriptorProto_EnumReservedRange& from);
@@ -2428,7 +2428,7 @@ class PROTOBUF_EXPORT EnumDescriptorProto PROTOBUF_FINAL :
     public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.EnumDescriptorProto) */ {
  public:
   inline EnumDescriptorProto() : EnumDescriptorProto(nullptr) {}
-  virtual ~EnumDescriptorProto();
+  ~EnumDescriptorProto() override;
   explicit constexpr EnumDescriptorProto(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);
 
   EnumDescriptorProto(const EnumDescriptorProto& from);
@@ -2664,7 +2664,7 @@ class PROTOBUF_EXPORT EnumValueDescriptorProto PROTOBUF_FINAL :
     public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.EnumValueDescriptorProto) */ {
  public:
   inline EnumValueDescriptorProto() : EnumValueDescriptorProto(nullptr) {}
-  virtual ~EnumValueDescriptorProto();
+  ~EnumValueDescriptorProto() override;
   explicit constexpr EnumValueDescriptorProto(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);
 
   EnumValueDescriptorProto(const EnumValueDescriptorProto& from);
@@ -2847,7 +2847,7 @@ class PROTOBUF_EXPORT ServiceDescriptorProto PROTOBUF_FINAL :
     public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.ServiceDescriptorProto) */ {
  public:
   inline ServiceDescriptorProto() : ServiceDescriptorProto(nullptr) {}
-  virtual ~ServiceDescriptorProto();
+  ~ServiceDescriptorProto() override;
   explicit constexpr ServiceDescriptorProto(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);
 
   ServiceDescriptorProto(const ServiceDescriptorProto& from);
@@ -3035,7 +3035,7 @@ class PROTOBUF_EXPORT MethodDescriptorProto PROTOBUF_FINAL :
     public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.MethodDescriptorProto) */ {
  public:
   inline MethodDescriptorProto() : MethodDescriptorProto(nullptr) {}
-  virtual ~MethodDescriptorProto();
+  ~MethodDescriptorProto() override;
   explicit constexpr MethodDescriptorProto(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);
 
   MethodDescriptorProto(const MethodDescriptorProto& from);
@@ -3273,7 +3273,7 @@ class PROTOBUF_EXPORT FileOptions PROTOBUF_FINAL :
     public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.FileOptions) */ {
  public:
   inline FileOptions() : FileOptions(nullptr) {}
-  virtual ~FileOptions();
+  ~FileOptions() override;
   explicit constexpr FileOptions(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);
 
   FileOptions(const FileOptions& from);
@@ -3806,7 +3806,7 @@ class PROTOBUF_EXPORT MessageOptions PROTOBUF_FINAL :
     public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.MessageOptions) */ {
  public:
   inline MessageOptions() : MessageOptions(nullptr) {}
-  virtual ~MessageOptions();
+  ~MessageOptions() override;
   explicit constexpr MessageOptions(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);
 
   MessageOptions(const MessageOptions& from);
@@ -4017,7 +4017,7 @@ class PROTOBUF_EXPORT FieldOptions PROTOBUF_FINAL :
     public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.FieldOptions) */ {
  public:
   inline FieldOptions() : FieldOptions(nullptr) {}
-  virtual ~FieldOptions();
+  ~FieldOptions() override;
   explicit constexpr FieldOptions(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);
 
   FieldOptions(const FieldOptions& from);
@@ -4322,7 +4322,7 @@ class PROTOBUF_EXPORT OneofOptions PROTOBUF_FINAL :
     public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.OneofOptions) */ {
  public:
   inline OneofOptions() : OneofOptions(nullptr) {}
-  virtual ~OneofOptions();
+  ~OneofOptions() override;
   explicit constexpr OneofOptions(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);
 
   OneofOptions(const OneofOptions& from);
@@ -4472,7 +4472,7 @@ class PROTOBUF_EXPORT EnumOptions PROTOBUF_FINAL :
     public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.EnumOptions) */ {
  public:
   inline EnumOptions() : EnumOptions(nullptr) {}
-  virtual ~EnumOptions();
+  ~EnumOptions() override;
   explicit constexpr EnumOptions(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);
 
   EnumOptions(const EnumOptions& from);
@@ -4653,7 +4653,7 @@ class PROTOBUF_EXPORT EnumValueOptions PROTOBUF_FINAL :
     public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.EnumValueOptions) */ {
  public:
   inline EnumValueOptions() : EnumValueOptions(nullptr) {}
-  virtual ~EnumValueOptions();
+  ~EnumValueOptions() override;
   explicit constexpr EnumValueOptions(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);
 
   EnumValueOptions(const EnumValueOptions& from);
@@ -4819,7 +4819,7 @@ class PROTOBUF_EXPORT ServiceOptions PROTOBUF_FINAL :
     public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.ServiceOptions) */ {
  public:
   inline ServiceOptions() : ServiceOptions(nullptr) {}
-  virtual ~ServiceOptions();
+  ~ServiceOptions() override;
   explicit constexpr ServiceOptions(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);
 
   ServiceOptions(const ServiceOptions& from);
@@ -4985,7 +4985,7 @@ class PROTOBUF_EXPORT MethodOptions PROTOBUF_FINAL :
     public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.MethodOptions) */ {
  public:
   inline MethodOptions() : MethodOptions(nullptr) {}
-  virtual ~MethodOptions();
+  ~MethodOptions() override;
   explicit constexpr MethodOptions(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);
 
   MethodOptions(const MethodOptions& from);
@@ -5198,7 +5198,7 @@ class PROTOBUF_EXPORT UninterpretedOption_NamePart PROTOBUF_FINAL :
     public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.UninterpretedOption.NamePart) */ {
  public:
   inline UninterpretedOption_NamePart() : UninterpretedOption_NamePart(nullptr) {}
-  virtual ~UninterpretedOption_NamePart();
+  ~UninterpretedOption_NamePart() override;
   explicit constexpr UninterpretedOption_NamePart(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);
 
   UninterpretedOption_NamePart(const UninterpretedOption_NamePart& from);
@@ -5364,7 +5364,7 @@ class PROTOBUF_EXPORT UninterpretedOption PROTOBUF_FINAL :
     public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.UninterpretedOption) */ {
  public:
   inline UninterpretedOption() : UninterpretedOption(nullptr) {}
-  virtual ~UninterpretedOption();
+  ~UninterpretedOption() override;
   explicit constexpr UninterpretedOption(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);
 
   UninterpretedOption(const UninterpretedOption& from);
@@ -5619,7 +5619,7 @@ class PROTOBUF_EXPORT SourceCodeInfo_Location PROTOBUF_FINAL :
     public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.SourceCodeInfo.Location) */ {
  public:
   inline SourceCodeInfo_Location() : SourceCodeInfo_Location(nullptr) {}
-  virtual ~SourceCodeInfo_Location();
+  ~SourceCodeInfo_Location() override;
   explicit constexpr SourceCodeInfo_Location(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);
 
   SourceCodeInfo_Location(const SourceCodeInfo_Location& from);
@@ -5863,7 +5863,7 @@ class PROTOBUF_EXPORT SourceCodeInfo PROTOBUF_FINAL :
     public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.SourceCodeInfo) */ {
  public:
   inline SourceCodeInfo() : SourceCodeInfo(nullptr) {}
-  virtual ~SourceCodeInfo();
+  ~SourceCodeInfo() override;
   explicit constexpr SourceCodeInfo(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);
 
   SourceCodeInfo(const SourceCodeInfo& from);
@@ -6012,7 +6012,7 @@ class PROTOBUF_EXPORT GeneratedCodeInfo_Annotation PROTOBUF_FINAL :
     public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.GeneratedCodeInfo.Annotation) */ {
  public:
   inline GeneratedCodeInfo_Annotation() : GeneratedCodeInfo_Annotation(nullptr) {}
-  virtual ~GeneratedCodeInfo_Annotation();
+  ~GeneratedCodeInfo_Annotation() override;
   explicit constexpr GeneratedCodeInfo_Annotation(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);
 
   GeneratedCodeInfo_Annotation(const GeneratedCodeInfo_Annotation& from);
@@ -6215,7 +6215,7 @@ class PROTOBUF_EXPORT GeneratedCodeInfo PROTOBUF_FINAL :
     public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.GeneratedCodeInfo) */ {
  public:
   inline GeneratedCodeInfo() : GeneratedCodeInfo(nullptr) {}
-  virtual ~GeneratedCodeInfo();
+  ~GeneratedCodeInfo() override;
   explicit constexpr GeneratedCodeInfo(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);
 
   GeneratedCodeInfo(const GeneratedCodeInfo& from);

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

@@ -13,7 +13,7 @@
 #error incompatible with your Protocol Buffer headers. Please update
 #error your headers.
 #endif
-#if 3015002 < PROTOBUF_MIN_PROTOC_VERSION
+#if 3015006 < 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.
@@ -69,7 +69,7 @@ class PROTOBUF_EXPORT Duration PROTOBUF_FINAL :
     public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.Duration) */ {
  public:
   inline Duration() : Duration(nullptr) {}
-  virtual ~Duration();
+  ~Duration() override;
   explicit constexpr Duration(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);
 
   Duration(const Duration& from);

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

@@ -13,7 +13,7 @@
 #error incompatible with your Protocol Buffer headers. Please update
 #error your headers.
 #endif
-#if 3015002 < PROTOBUF_MIN_PROTOC_VERSION
+#if 3015006 < 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.
@@ -69,7 +69,7 @@ class PROTOBUF_EXPORT Empty PROTOBUF_FINAL :
     public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.Empty) */ {
  public:
   inline Empty() : Empty(nullptr) {}
-  virtual ~Empty();
+  ~Empty() override;
   explicit constexpr Empty(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);
 
   Empty(const Empty& from);

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

@@ -13,7 +13,7 @@
 #error incompatible with your Protocol Buffer headers. Please update
 #error your headers.
 #endif
-#if 3015002 < PROTOBUF_MIN_PROTOC_VERSION
+#if 3015006 < 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.
@@ -69,7 +69,7 @@ class PROTOBUF_EXPORT FieldMask PROTOBUF_FINAL :
     public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.FieldMask) */ {
  public:
   inline FieldMask() : FieldMask(nullptr) {}
-  virtual ~FieldMask();
+  ~FieldMask() override;
   explicit constexpr FieldMask(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);
 
   FieldMask(const FieldMask& from);

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

@@ -133,6 +133,8 @@
 #else
 #ifdef __APPLE__
 #include <machine/endian.h>  // __BYTE_ORDER
+#elif defined(__FreeBSD__)
+#include <sys/endian.h>  // __BYTE_ORDER
 #else
 #include <endian.h>  // __BYTE_ORDER
 #endif

+ 0 - 1
src/google/protobuf/parse_context.h

@@ -348,7 +348,6 @@ class PROTOBUF_EXPORT EpsCopyInputStream {
     if (ptr - buffer_end_ > limit_) return nullptr;
     while (limit_ > kSlopBytes) {
       size_t chunk_size = buffer_end_ + kSlopBytes - ptr;
-      GOOGLE_DCHECK_GE(chunk_size, static_cast<size_t>(0));
       append(ptr, chunk_size);
       ptr = Next();
       if (ptr == nullptr) return limit_end_;

+ 0 - 7
src/google/protobuf/port.h

@@ -37,11 +37,4 @@
 #define GOOGLE_PROTOBUF_PORT_H__
 
 
-#include <google/protobuf/stubs/port.h>
-
-// Protobuf intends to move into the pb:: namespace.
-namespace protobuf_future_namespace_placeholder {}
-namespace pb = ::protobuf_future_namespace_placeholder;
-
-
 #endif  // GOOGLE_PROTOBUF_PORT_H__

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

@@ -337,7 +337,7 @@
 
 // Shared google3/opensource definitions. //////////////////////////////////////
 
-#define PROTOBUF_VERSION 3015002
+#define PROTOBUF_VERSION 3015006
 #define PROTOBUF_MIN_HEADER_VERSION_FOR_PROTOC 3015000
 #define PROTOBUF_MIN_PROTOC_VERSION 3015000
 #define PROTOBUF_VERSION_SUFFIX ""

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

@@ -13,7 +13,7 @@
 #error incompatible with your Protocol Buffer headers. Please update
 #error your headers.
 #endif
-#if 3015002 < PROTOBUF_MIN_PROTOC_VERSION
+#if 3015006 < 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.
@@ -69,7 +69,7 @@ class PROTOBUF_EXPORT SourceContext PROTOBUF_FINAL :
     public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.SourceContext) */ {
  public:
   inline SourceContext() : SourceContext(nullptr) {}
-  virtual ~SourceContext();
+  ~SourceContext() override;
   explicit constexpr SourceContext(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);
 
   SourceContext(const SourceContext& from);

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

@@ -13,7 +13,7 @@
 #error incompatible with your Protocol Buffer headers. Please update
 #error your headers.
 #endif
-#if 3015002 < PROTOBUF_MIN_PROTOC_VERSION
+#if 3015006 < 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.
@@ -134,7 +134,7 @@ class PROTOBUF_EXPORT Struct PROTOBUF_FINAL :
     public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.Struct) */ {
  public:
   inline Struct() : Struct(nullptr) {}
-  virtual ~Struct();
+  ~Struct() override;
   explicit constexpr Struct(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);
 
   Struct(const Struct& from);
@@ -278,7 +278,7 @@ class PROTOBUF_EXPORT Value PROTOBUF_FINAL :
     public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.Value) */ {
  public:
   inline Value() : Value(nullptr) {}
-  virtual ~Value();
+  ~Value() override;
   explicit constexpr Value(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);
 
   Value(const Value& from);
@@ -530,7 +530,7 @@ class PROTOBUF_EXPORT ListValue PROTOBUF_FINAL :
     public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.ListValue) */ {
  public:
   inline ListValue() : ListValue(nullptr) {}
-  virtual ~ListValue();
+  ~ListValue() override;
   explicit constexpr ListValue(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);
 
   ListValue(const ListValue& from);

+ 1 - 1
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 3015002
+#define GOOGLE_PROTOBUF_VERSION 3015006
 
 // A suffix string for alpha, beta or rc releases. Empty for stable releases.
 #define GOOGLE_PROTOBUF_VERSION_SUFFIX ""

+ 1 - 3
src/google/protobuf/stubs/logging.h

@@ -33,6 +33,7 @@
 
 #include <google/protobuf/stubs/macros.h>
 #include <google/protobuf/stubs/port.h>
+#include <google/protobuf/stubs/status.h>
 
 #include <google/protobuf/port_def.inc>
 
@@ -64,9 +65,6 @@ enum LogLevel {
 };
 
 class StringPiece;
-namespace util {
-class Status;
-}
 class uint128;
 namespace internal {
 

+ 2 - 0
src/google/protobuf/stubs/port.h

@@ -59,6 +59,8 @@
 #else
 #ifdef __APPLE__
 #include <machine/endian.h>  // __BYTE_ORDER
+#elif defined(__FreeBSD__)
+#include <sys/endian.h>  // __BYTE_ORDER
 #else
 #include <endian.h>  // __BYTE_ORDER
 #endif

+ 159 - 31
src/google/protobuf/stubs/status.cc

@@ -37,42 +37,44 @@
 namespace google {
 namespace protobuf {
 namespace util {
-namespace error {
-inline std::string CodeEnumToString(error::Code code) {
+namespace status_internal {
+namespace {
+
+inline std::string StatusCodeToString(StatusCode code) {
   switch (code) {
-    case OK:
+    case StatusCode::kOk:
       return "OK";
-    case CANCELLED:
+    case StatusCode::kCancelled:
       return "CANCELLED";
-    case UNKNOWN:
+    case StatusCode::kUnknown:
       return "UNKNOWN";
-    case INVALID_ARGUMENT:
+    case StatusCode::kInvalidArgument:
       return "INVALID_ARGUMENT";
-    case DEADLINE_EXCEEDED:
+    case StatusCode::kDeadlineExceeded:
       return "DEADLINE_EXCEEDED";
-    case NOT_FOUND:
+    case StatusCode::kNotFound:
       return "NOT_FOUND";
-    case ALREADY_EXISTS:
+    case StatusCode::kAlreadyExists:
       return "ALREADY_EXISTS";
-    case PERMISSION_DENIED:
+    case StatusCode::kPermissionDenied:
       return "PERMISSION_DENIED";
-    case UNAUTHENTICATED:
+    case StatusCode::kUnauthenticated:
       return "UNAUTHENTICATED";
-    case RESOURCE_EXHAUSTED:
+    case StatusCode::kResourceExhausted:
       return "RESOURCE_EXHAUSTED";
-    case FAILED_PRECONDITION:
+    case StatusCode::kFailedPrecondition:
       return "FAILED_PRECONDITION";
-    case ABORTED:
+    case StatusCode::kAborted:
       return "ABORTED";
-    case OUT_OF_RANGE:
+    case StatusCode::kOutOfRange:
       return "OUT_OF_RANGE";
-    case UNIMPLEMENTED:
+    case StatusCode::kUnimplemented:
       return "UNIMPLEMENTED";
-    case INTERNAL:
+    case StatusCode::kInternal:
       return "INTERNAL";
-    case UNAVAILABLE:
+    case StatusCode::kUnavailable:
       return "UNAVAILABLE";
-    case DATA_LOSS:
+    case StatusCode::kDataLoss:
       return "DATA_LOSS";
   }
 
@@ -80,18 +82,14 @@ inline std::string CodeEnumToString(error::Code code) {
   // above switch.
   return "UNKNOWN";
 }
-}  // namespace error.
 
-const Status Status::OK = Status();
-const Status Status::CANCELLED = Status(error::CANCELLED, "");
-const Status Status::UNKNOWN = Status(error::UNKNOWN, "");
+}  // namespace
 
-Status::Status() : error_code_(error::OK) {
-}
+Status::Status() : error_code_(StatusCode::kOk) {}
 
-Status::Status(error::Code error_code, StringPiece error_message)
+Status::Status(StatusCode error_code, StringPiece error_message)
     : error_code_(error_code) {
-  if (error_code != error::OK) {
+  if (error_code != StatusCode::kOk) {
     error_message_ = error_message.ToString();
   }
 }
@@ -112,23 +110,153 @@ bool Status::operator==(const Status& x) const {
 }
 
 std::string Status::ToString() const {
-  if (error_code_ == error::OK) {
+  if (error_code_ == StatusCode::kOk) {
     return "OK";
   } else {
     if (error_message_.empty()) {
-      return error::CodeEnumToString(error_code_);
+      return StatusCodeToString(error_code_);
     } else {
-      return error::CodeEnumToString(error_code_) + ":" +
-          error_message_;
+      return StatusCodeToString(error_code_) + ":" + error_message_;
     }
   }
 }
 
+Status OkStatus() { return Status(); }
+
 std::ostream& operator<<(std::ostream& os, const Status& x) {
   os << x.ToString();
   return os;
 }
 
+bool IsAborted(const Status& status) {
+  return status.code() == StatusCode::kAborted;
+}
+
+bool IsAlreadyExists(const Status& status) {
+  return status.code() == StatusCode::kAlreadyExists;
+}
+
+bool IsCancelled(const Status& status) {
+  return status.code() == StatusCode::kCancelled;
+}
+
+bool IsDataLoss(const Status& status) {
+  return status.code() == StatusCode::kDataLoss;
+}
+
+bool IsDeadlineExceeded(const Status& status) {
+  return status.code() == StatusCode::kDeadlineExceeded;
+}
+
+bool IsFailedPrecondition(const Status& status) {
+  return status.code() == StatusCode::kFailedPrecondition;
+}
+
+bool IsInternal(const Status& status) {
+  return status.code() == StatusCode::kInternal;
+}
+
+bool IsInvalidArgument(const Status& status) {
+  return status.code() == StatusCode::kInvalidArgument;
+}
+
+bool IsNotFound(const Status& status) {
+  return status.code() == StatusCode::kNotFound;
+}
+
+bool IsOutOfRange(const Status& status) {
+  return status.code() == StatusCode::kOutOfRange;
+}
+
+bool IsPermissionDenied(const Status& status) {
+  return status.code() == StatusCode::kPermissionDenied;
+}
+
+bool IsResourceExhausted(const Status& status) {
+  return status.code() == StatusCode::kResourceExhausted;
+}
+
+bool IsUnauthenticated(const Status& status) {
+  return status.code() == StatusCode::kUnauthenticated;
+}
+
+bool IsUnavailable(const Status& status) {
+  return status.code() == StatusCode::kUnavailable;
+}
+
+bool IsUnimplemented(const Status& status) {
+  return status.code() == StatusCode::kUnimplemented;
+}
+
+bool IsUnknown(const Status& status) {
+  return status.code() == StatusCode::kUnknown;
+}
+
+Status AbortedError(StringPiece message) {
+  return Status(StatusCode::kAborted, message);
+}
+
+Status AlreadyExistsError(StringPiece message) {
+  return Status(StatusCode::kAlreadyExists, message);
+}
+
+Status CancelledError(StringPiece message) {
+  return Status(StatusCode::kCancelled, message);
+}
+
+Status DataLossError(StringPiece message) {
+  return Status(StatusCode::kDataLoss, message);
+}
+
+Status DeadlineExceededError(StringPiece message) {
+  return Status(StatusCode::kDeadlineExceeded, message);
+}
+
+Status FailedPreconditionError(StringPiece message) {
+  return Status(StatusCode::kFailedPrecondition, message);
+}
+
+Status InternalError(StringPiece message) {
+  return Status(StatusCode::kInternal, message);
+}
+
+Status InvalidArgumentError(StringPiece message) {
+  return Status(StatusCode::kInvalidArgument, message);
+}
+
+Status NotFoundError(StringPiece message) {
+  return Status(StatusCode::kNotFound, message);
+}
+
+Status OutOfRangeError(StringPiece message) {
+  return Status(StatusCode::kOutOfRange, message);
+}
+
+Status PermissionDeniedError(StringPiece message) {
+  return Status(StatusCode::kPermissionDenied, message);
+}
+
+Status ResourceExhaustedError(StringPiece message) {
+  return Status(StatusCode::kResourceExhausted, message);
+}
+
+Status UnauthenticatedError(StringPiece message) {
+  return Status(StatusCode::kUnauthenticated, message);
+}
+
+Status UnavailableError(StringPiece message) {
+  return Status(StatusCode::kUnavailable, message);
+}
+
+Status UnimplementedError(StringPiece message) {
+  return Status(StatusCode::kUnimplemented, message);
+}
+
+Status UnknownError(StringPiece message) {
+  return Status(StatusCode::kUnknown, message);
+}
+
+}  // namespace status_internal
 }  // namespace util
 }  // namespace protobuf
 }  // namespace google

+ 113 - 42
src/google/protobuf/stubs/status.h

@@ -27,13 +27,12 @@
 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
 #ifndef GOOGLE_PROTOBUF_STUBS_STATUS_H_
 #define GOOGLE_PROTOBUF_STUBS_STATUS_H_
 
-#include <iosfwd>
 #include <string>
 
-#include <google/protobuf/stubs/common.h>
 #include <google/protobuf/stubs/stringpiece.h>
 
 #include <google/protobuf/port_def.inc>
@@ -41,28 +40,28 @@
 namespace google {
 namespace protobuf {
 namespace util {
-namespace error {
+namespace status_internal {
+
 // These values must match error codes defined in google/rpc/code.proto.
-enum Code {
-  OK = 0,
-  CANCELLED = 1,
-  UNKNOWN = 2,
-  INVALID_ARGUMENT = 3,
-  DEADLINE_EXCEEDED = 4,
-  NOT_FOUND = 5,
-  ALREADY_EXISTS = 6,
-  PERMISSION_DENIED = 7,
-  UNAUTHENTICATED = 16,
-  RESOURCE_EXHAUSTED = 8,
-  FAILED_PRECONDITION = 9,
-  ABORTED = 10,
-  OUT_OF_RANGE = 11,
-  UNIMPLEMENTED = 12,
-  INTERNAL = 13,
-  UNAVAILABLE = 14,
-  DATA_LOSS = 15,
+enum class StatusCode : int {
+  kOk = 0,
+  kCancelled = 1,
+  kUnknown = 2,
+  kInvalidArgument = 3,
+  kDeadlineExceeded = 4,
+  kNotFound = 5,
+  kAlreadyExists = 6,
+  kPermissionDenied = 7,
+  kUnauthenticated = 16,
+  kResourceExhausted = 8,
+  kFailedPrecondition = 9,
+  kAborted = 10,
+  kOutOfRange = 11,
+  kUnimplemented = 12,
+  kInternal = 13,
+  kUnavailable = 14,
+  kDataLoss = 15,
 };
-}  // namespace error
 
 class PROTOBUF_EXPORT Status {
  public:
@@ -71,31 +70,16 @@ class PROTOBUF_EXPORT Status {
 
   // Create a status in the canonical error space with the specified
   // code, and error message.  If "code == 0", error_message is
-  // ignored and a Status object identical to Status::OK is
+  // ignored and a Status object identical to Status::kOk is
   // constructed.
-  Status(error::Code error_code, StringPiece error_message);
+  Status(StatusCode error_code, StringPiece error_message);
   Status(const Status&);
   Status& operator=(const Status& x);
   ~Status() {}
 
-  // Some pre-defined Status objects
-  static const Status OK;             // Identical to 0-arg constructor
-  static const Status CANCELLED;
-  static const Status UNKNOWN;
-
   // Accessor
-  bool ok() const {
-    return error_code_ == error::OK;
-  }
-  int error_code() const {
-    return error_code_;
-  }
-  error::Code code() const {
-    return error_code_;
-  }
-  StringPiece error_message() const {
-    return error_message_;
-  }
+  bool ok() const { return error_code_ == StatusCode::kOk; }
+  StatusCode code() const { return error_code_; }
   StringPiece message() const {
     return error_message_;
   }
@@ -109,13 +93,100 @@ class PROTOBUF_EXPORT Status {
   std::string ToString() const;
 
  private:
-  error::Code error_code_;
+  StatusCode error_code_;
   std::string error_message_;
 };
 
+// Returns an OK status, equivalent to a default constructed instance. Prefer
+// usage of `OkStatus()` when constructing such an OK status.
+PROTOBUF_EXPORT Status OkStatus();
+
 // Prints a human-readable representation of 'x' to 'os'.
 PROTOBUF_EXPORT std::ostream& operator<<(std::ostream& os, const Status& x);
 
+// These convenience functions return `true` if a given status matches the
+// `StatusCode` error code of its associated function.
+PROTOBUF_EXPORT bool IsAborted(const Status& status);
+PROTOBUF_EXPORT bool IsAlreadyExists(const Status& status);
+PROTOBUF_EXPORT bool IsCancelled(const Status& status);
+PROTOBUF_EXPORT bool IsDataLoss(const Status& status);
+PROTOBUF_EXPORT bool IsDeadlineExceeded(const Status& status);
+PROTOBUF_EXPORT bool IsFailedPrecondition(const Status& status);
+PROTOBUF_EXPORT bool IsInternal(const Status& status);
+PROTOBUF_EXPORT bool IsInvalidArgument(const Status& status);
+PROTOBUF_EXPORT bool IsNotFound(const Status& status);
+PROTOBUF_EXPORT bool IsOutOfRange(const Status& status);
+PROTOBUF_EXPORT bool IsPermissionDenied(const Status& status);
+PROTOBUF_EXPORT bool IsResourceExhausted(const Status& status);
+PROTOBUF_EXPORT bool IsUnauthenticated(const Status& status);
+PROTOBUF_EXPORT bool IsUnavailable(const Status& status);
+PROTOBUF_EXPORT bool IsUnimplemented(const Status& status);
+PROTOBUF_EXPORT bool IsUnknown(const Status& status);
+
+// These convenience functions create an `Status` object with an error code as
+// indicated by the associated function name, using the error message passed in
+// `message`.
+//
+// These functions are intentionally named `*Error` rather than `*Status` to
+// match the names from Abseil:
+// https://github.com/abseil/abseil-cpp/blob/2e9532cc6c701a8323d0cffb468999ab804095ab/absl/status/status.h#L716
+PROTOBUF_EXPORT Status AbortedError(StringPiece message);
+PROTOBUF_EXPORT Status AlreadyExistsError(StringPiece message);
+PROTOBUF_EXPORT Status CancelledError(StringPiece message);
+PROTOBUF_EXPORT Status DataLossError(StringPiece message);
+PROTOBUF_EXPORT Status DeadlineExceededError(StringPiece message);
+PROTOBUF_EXPORT Status FailedPreconditionError(StringPiece message);
+PROTOBUF_EXPORT Status InternalError(StringPiece message);
+PROTOBUF_EXPORT Status InvalidArgumentError(StringPiece message);
+PROTOBUF_EXPORT Status NotFoundError(StringPiece message);
+PROTOBUF_EXPORT Status OutOfRangeError(StringPiece message);
+PROTOBUF_EXPORT Status PermissionDeniedError(StringPiece message);
+PROTOBUF_EXPORT Status ResourceExhaustedError(StringPiece message);
+PROTOBUF_EXPORT Status UnauthenticatedError(StringPiece message);
+PROTOBUF_EXPORT Status UnavailableError(StringPiece message);
+PROTOBUF_EXPORT Status UnimplementedError(StringPiece message);
+PROTOBUF_EXPORT Status UnknownError(StringPiece message);
+
+}  // namespace status_internal
+
+using ::google::protobuf::util::status_internal::Status;
+using ::google::protobuf::util::status_internal::StatusCode;
+
+using ::google::protobuf::util::status_internal::IsAborted;
+using ::google::protobuf::util::status_internal::IsAlreadyExists;
+using ::google::protobuf::util::status_internal::IsCancelled;
+using ::google::protobuf::util::status_internal::IsDataLoss;
+using ::google::protobuf::util::status_internal::IsDeadlineExceeded;
+using ::google::protobuf::util::status_internal::IsFailedPrecondition;
+using ::google::protobuf::util::status_internal::IsInternal;
+using ::google::protobuf::util::status_internal::IsInvalidArgument;
+using ::google::protobuf::util::status_internal::IsNotFound;
+using ::google::protobuf::util::status_internal::IsOutOfRange;
+using ::google::protobuf::util::status_internal::IsPermissionDenied;
+using ::google::protobuf::util::status_internal::IsResourceExhausted;
+using ::google::protobuf::util::status_internal::IsUnauthenticated;
+using ::google::protobuf::util::status_internal::IsUnavailable;
+using ::google::protobuf::util::status_internal::IsUnimplemented;
+using ::google::protobuf::util::status_internal::IsUnknown;
+
+using ::google::protobuf::util::status_internal::AbortedError;
+using ::google::protobuf::util::status_internal::AlreadyExistsError;
+using ::google::protobuf::util::status_internal::CancelledError;
+using ::google::protobuf::util::status_internal::DataLossError;
+using ::google::protobuf::util::status_internal::DeadlineExceededError;
+using ::google::protobuf::util::status_internal::FailedPreconditionError;
+using ::google::protobuf::util::status_internal::InternalError;
+using ::google::protobuf::util::status_internal::InvalidArgumentError;
+using ::google::protobuf::util::status_internal::NotFoundError;
+using ::google::protobuf::util::status_internal::OkStatus;
+using ::google::protobuf::util::status_internal::OutOfRangeError;
+using ::google::protobuf::util::status_internal::PermissionDeniedError;
+using ::google::protobuf::util::status_internal::ResourceExhaustedError;
+using ::google::protobuf::util::status_internal::UnauthenticatedError;
+using ::google::protobuf::util::status_internal::UnavailableError;
+using ::google::protobuf::util::status_internal::UnimplementedError;
+using ::google::protobuf::util::status_internal::UnknownError;
+
 }  // namespace util
 }  // namespace protobuf
 }  // namespace google

+ 173 - 33
src/google/protobuf/stubs/status_test.cc

@@ -37,26 +37,170 @@
 namespace google {
 namespace protobuf {
 namespace {
-TEST(Status, Empty) {
-  util::Status status;
-  EXPECT_EQ(util::error::OK, util::Status::OK.error_code());
-  EXPECT_EQ(util::error::OK, util::Status::OK.code());
-  EXPECT_EQ("OK", util::Status::OK.ToString());
-}
 
-TEST(Status, GenericCodes) {
-  EXPECT_EQ(util::error::OK, util::Status::OK.error_code());
-  EXPECT_EQ(util::error::OK, util::Status::OK.code());
-  EXPECT_EQ(util::error::CANCELLED, util::Status::CANCELLED.error_code());
-  EXPECT_EQ(util::error::CANCELLED, util::Status::CANCELLED.code());
-  EXPECT_EQ(util::error::UNKNOWN, util::Status::UNKNOWN.error_code());
-  EXPECT_EQ(util::error::UNKNOWN, util::Status::UNKNOWN.code());
+TEST(Status, Constructor) {
+  EXPECT_EQ(util::StatusCode::kOk,
+            util::Status(util::StatusCode::kOk, "").code());
+  EXPECT_EQ(util::StatusCode::kCancelled,
+            util::Status(util::StatusCode::kCancelled, "").code());
+  EXPECT_EQ(util::StatusCode::kUnknown,
+            util::Status(util::StatusCode::kUnknown, "").code());
+  EXPECT_EQ(util::StatusCode::kInvalidArgument,
+            util::Status(util::StatusCode::kInvalidArgument, "").code());
+  EXPECT_EQ(util::StatusCode::kDeadlineExceeded,
+            util::Status(util::StatusCode::kDeadlineExceeded, "").code());
+  EXPECT_EQ(util::StatusCode::kNotFound,
+            util::Status(util::StatusCode::kNotFound, "").code());
+  EXPECT_EQ(util::StatusCode::kAlreadyExists,
+            util::Status(util::StatusCode::kAlreadyExists, "").code());
+  EXPECT_EQ(util::StatusCode::kPermissionDenied,
+            util::Status(util::StatusCode::kPermissionDenied, "").code());
+  EXPECT_EQ(util::StatusCode::kUnauthenticated,
+            util::Status(util::StatusCode::kUnauthenticated, "").code());
+  EXPECT_EQ(util::StatusCode::kResourceExhausted,
+            util::Status(util::StatusCode::kResourceExhausted, "").code());
+  EXPECT_EQ(util::StatusCode::kFailedPrecondition,
+            util::Status(util::StatusCode::kFailedPrecondition, "").code());
+  EXPECT_EQ(util::StatusCode::kAborted,
+            util::Status(util::StatusCode::kAborted, "").code());
+  EXPECT_EQ(util::StatusCode::kOutOfRange,
+            util::Status(util::StatusCode::kOutOfRange, "").code());
+  EXPECT_EQ(util::StatusCode::kUnimplemented,
+            util::Status(util::StatusCode::kUnimplemented, "").code());
+  EXPECT_EQ(util::StatusCode::kInternal,
+            util::Status(util::StatusCode::kInternal, "").code());
+  EXPECT_EQ(util::StatusCode::kUnavailable,
+            util::Status(util::StatusCode::kUnavailable, "").code());
+  EXPECT_EQ(util::StatusCode::kDataLoss,
+            util::Status(util::StatusCode::kDataLoss, "").code());
 }
 
 TEST(Status, ConstructorZero) {
-  util::Status status(util::error::OK, "msg");
+  util::Status status(util::StatusCode::kOk, "msg");
   EXPECT_TRUE(status.ok());
   EXPECT_EQ("OK", status.ToString());
+  EXPECT_EQ(util::OkStatus(), status);
+}
+
+TEST(Status, ConvenienceConstructors) {
+  EXPECT_EQ(util::StatusCode::kOk, util::OkStatus().code());
+  EXPECT_EQ("", util::OkStatus().message());
+
+  EXPECT_EQ(util::StatusCode::kCancelled, util::CancelledError("").code());
+  EXPECT_EQ("", util::CancelledError("").message());
+  EXPECT_EQ("foo", util::CancelledError("foo").message());
+  EXPECT_EQ("bar", util::CancelledError("bar").message());
+
+  EXPECT_EQ(util::StatusCode::kUnknown, util::UnknownError("").code());
+  EXPECT_EQ("", util::UnknownError("").message());
+  EXPECT_EQ("foo", util::UnknownError("foo").message());
+  EXPECT_EQ("bar", util::UnknownError("bar").message());
+
+  EXPECT_EQ(util::StatusCode::kInvalidArgument,
+            util::InvalidArgumentError("").code());
+  EXPECT_EQ("", util::InvalidArgumentError("").message());
+  EXPECT_EQ("foo", util::InvalidArgumentError("foo").message());
+  EXPECT_EQ("bar", util::InvalidArgumentError("bar").message());
+
+  EXPECT_EQ(util::StatusCode::kDeadlineExceeded,
+            util::DeadlineExceededError("").code());
+  EXPECT_EQ("", util::DeadlineExceededError("").message());
+  EXPECT_EQ("foo", util::DeadlineExceededError("foo").message());
+  EXPECT_EQ("bar", util::DeadlineExceededError("bar").message());
+
+  EXPECT_EQ(util::StatusCode::kNotFound, util::NotFoundError("").code());
+  EXPECT_EQ("", util::NotFoundError("").message());
+  EXPECT_EQ("foo", util::NotFoundError("foo").message());
+  EXPECT_EQ("bar", util::NotFoundError("bar").message());
+
+  EXPECT_EQ(util::StatusCode::kAlreadyExists,
+            util::AlreadyExistsError("").code());
+  EXPECT_EQ("", util::AlreadyExistsError("").message());
+  EXPECT_EQ("foo", util::AlreadyExistsError("foo").message());
+  EXPECT_EQ("bar", util::AlreadyExistsError("bar").message());
+
+  EXPECT_EQ(util::StatusCode::kPermissionDenied,
+            util::PermissionDeniedError("").code());
+  EXPECT_EQ("", util::PermissionDeniedError("").message());
+  EXPECT_EQ("foo", util::PermissionDeniedError("foo").message());
+  EXPECT_EQ("bar", util::PermissionDeniedError("bar").message());
+
+  EXPECT_EQ(util::StatusCode::kUnauthenticated,
+            util::UnauthenticatedError("").code());
+  EXPECT_EQ("", util::UnauthenticatedError("").message());
+  EXPECT_EQ("foo", util::UnauthenticatedError("foo").message());
+  EXPECT_EQ("bar", util::UnauthenticatedError("bar").message());
+
+  EXPECT_EQ(util::StatusCode::kResourceExhausted,
+            util::ResourceExhaustedError("").code());
+  EXPECT_EQ("", util::ResourceExhaustedError("").message());
+  EXPECT_EQ("foo", util::ResourceExhaustedError("foo").message());
+  EXPECT_EQ("bar", util::ResourceExhaustedError("bar").message());
+
+  EXPECT_EQ(util::StatusCode::kFailedPrecondition,
+            util::FailedPreconditionError("").code());
+  EXPECT_EQ("", util::FailedPreconditionError("").message());
+  EXPECT_EQ("foo", util::FailedPreconditionError("foo").message());
+  EXPECT_EQ("bar", util::FailedPreconditionError("bar").message());
+
+  EXPECT_EQ(util::StatusCode::kAborted, util::AbortedError("").code());
+  EXPECT_EQ("", util::AbortedError("").message());
+  EXPECT_EQ("foo", util::AbortedError("foo").message());
+  EXPECT_EQ("bar", util::AbortedError("bar").message());
+
+  EXPECT_EQ(util::StatusCode::kOutOfRange, util::OutOfRangeError("").code());
+  EXPECT_EQ("", util::OutOfRangeError("").message());
+  EXPECT_EQ("foo", util::OutOfRangeError("foo").message());
+  EXPECT_EQ("bar", util::OutOfRangeError("bar").message());
+
+  EXPECT_EQ(util::StatusCode::kUnimplemented,
+            util::UnimplementedError("").code());
+  EXPECT_EQ("", util::UnimplementedError("").message());
+  EXPECT_EQ("foo", util::UnimplementedError("foo").message());
+  EXPECT_EQ("bar", util::UnimplementedError("bar").message());
+
+  EXPECT_EQ(util::StatusCode::kInternal, util::InternalError("").code());
+  EXPECT_EQ("", util::InternalError("").message());
+  EXPECT_EQ("foo", util::InternalError("foo").message());
+  EXPECT_EQ("bar", util::InternalError("bar").message());
+
+  EXPECT_EQ(util::StatusCode::kUnavailable, util::UnavailableError("").code());
+  EXPECT_EQ("", util::UnavailableError("").message());
+  EXPECT_EQ("foo", util::UnavailableError("foo").message());
+  EXPECT_EQ("bar", util::UnavailableError("bar").message());
+
+  EXPECT_EQ(util::StatusCode::kDataLoss, util::DataLossError("").code());
+  EXPECT_EQ("", util::DataLossError("").message());
+  EXPECT_EQ("foo", util::DataLossError("foo").message());
+  EXPECT_EQ("bar", util::DataLossError("bar").message());
+}
+
+TEST(Status, ConvenienceTests) {
+  EXPECT_TRUE(util::OkStatus().ok());
+  EXPECT_TRUE(util::IsCancelled(util::CancelledError("")));
+  EXPECT_TRUE(util::IsUnknown(util::UnknownError("")));
+  EXPECT_TRUE(util::IsInvalidArgument(util::InvalidArgumentError("")));
+  EXPECT_TRUE(util::IsDeadlineExceeded(util::DeadlineExceededError("")));
+  EXPECT_TRUE(util::IsNotFound(util::NotFoundError("")));
+  EXPECT_TRUE(util::IsAlreadyExists(util::AlreadyExistsError("")));
+  EXPECT_TRUE(util::IsPermissionDenied(util::PermissionDeniedError("")));
+  EXPECT_TRUE(util::IsUnauthenticated(util::UnauthenticatedError("")));
+  EXPECT_TRUE(util::IsResourceExhausted(util::ResourceExhaustedError("")));
+  EXPECT_TRUE(util::IsFailedPrecondition(util::FailedPreconditionError("")));
+  EXPECT_TRUE(util::IsAborted(util::AbortedError("")));
+  EXPECT_TRUE(util::IsOutOfRange(util::OutOfRangeError("")));
+  EXPECT_TRUE(util::IsUnimplemented(util::UnimplementedError("")));
+  EXPECT_TRUE(util::IsInternal(util::InternalError("")));
+  EXPECT_TRUE(util::IsUnavailable(util::UnavailableError("")));
+  EXPECT_TRUE(util::IsDataLoss(util::DataLossError("")));
+}
+
+TEST(Status, Empty) {
+  util::Status status;
+  EXPECT_TRUE(status.ok());
+  EXPECT_EQ(util::OkStatus(), status);
+  EXPECT_EQ(util::StatusCode::kOk, status.code());
+  EXPECT_EQ("OK", status.ToString());
 }
 
 TEST(Status, CheckOK) {
@@ -67,38 +211,35 @@ TEST(Status, CheckOK) {
 }
 
 TEST(Status, ErrorMessage) {
-  util::Status status(util::error::INVALID_ARGUMENT, "");
+  util::Status status = util::InvalidArgumentError("");
   EXPECT_FALSE(status.ok());
-  EXPECT_EQ("", status.error_message().ToString());
   EXPECT_EQ("", status.message().ToString());
   EXPECT_EQ("INVALID_ARGUMENT", status.ToString());
-  status = util::Status(util::error::INVALID_ARGUMENT, "msg");
+  status = util::InvalidArgumentError("msg");
   EXPECT_FALSE(status.ok());
-  EXPECT_EQ("msg", status.error_message().ToString());
   EXPECT_EQ("msg", status.message().ToString());
   EXPECT_EQ("INVALID_ARGUMENT:msg", status.ToString());
-  status = util::Status(util::error::OK, "msg");
+  status = util::Status(util::StatusCode::kOk, "msg");
   EXPECT_TRUE(status.ok());
-  EXPECT_EQ("", status.error_message().ToString());
   EXPECT_EQ("", status.message().ToString());
   EXPECT_EQ("OK", status.ToString());
 }
 
 TEST(Status, Copy) {
-  util::Status a(util::error::UNKNOWN, "message");
+  util::Status a = util::UnknownError("message");
   util::Status b(a);
   ASSERT_EQ(a.ToString(), b.ToString());
 }
 
 TEST(Status, Assign) {
-  util::Status a(util::error::UNKNOWN, "message");
+  util::Status a = util::UnknownError("message");
   util::Status b;
   b = a;
   ASSERT_EQ(a.ToString(), b.ToString());
 }
 
 TEST(Status, AssignEmpty) {
-  util::Status a(util::error::UNKNOWN, "message");
+  util::Status a = util::UnknownError("message");
   util::Status b;
   a = b;
   ASSERT_EQ(std::string("OK"), a.ToString());
@@ -106,33 +247,32 @@ TEST(Status, AssignEmpty) {
   ASSERT_TRUE(a.ok());
 }
 
-TEST(Status, EqualsOK) {
-  ASSERT_EQ(util::Status::OK, util::Status());
-}
+TEST(Status, EqualsOK) { ASSERT_EQ(util::OkStatus(), util::Status()); }
 
 TEST(Status, EqualsSame) {
-  const util::Status a = util::Status(util::error::CANCELLED, "message");
-  const util::Status b = util::Status(util::error::CANCELLED, "message");
+  const util::Status a = util::CancelledError("message");
+  const util::Status b = util::CancelledError("message");
   ASSERT_EQ(a, b);
 }
 
 TEST(Status, EqualsCopy) {
-  const util::Status a = util::Status(util::error::CANCELLED, "message");
+  const util::Status a = util::CancelledError("message");
   const util::Status b = a;
   ASSERT_EQ(a, b);
 }
 
 TEST(Status, EqualsDifferentCode) {
-  const util::Status a = util::Status(util::error::CANCELLED, "message");
-  const util::Status b = util::Status(util::error::UNKNOWN, "message");
+  const util::Status a = util::CancelledError("message");
+  const util::Status b = util::UnknownError("message");
   ASSERT_NE(a, b);
 }
 
 TEST(Status, EqualsDifferentMessage) {
-  const util::Status a = util::Status(util::error::CANCELLED, "message");
-  const util::Status b = util::Status(util::error::CANCELLED, "another");
+  const util::Status a = util::CancelledError("message");
+  const util::Status b = util::CancelledError("another");
   ASSERT_NE(a, b);
 }
+
 }  // namespace
 }  // namespace protobuf
 }  // namespace google

+ 11 - 14
src/google/protobuf/stubs/statusor.h

@@ -32,7 +32,7 @@
 // object. StatusOr models the concept of an object that is either a
 // usable value, or an error Status explaining why such a value is
 // not present. To this end, StatusOr<T> does not allow its Status
-// value to be Status::OK. Further, StatusOr<T*> does not allow the
+// value to be OkStatus(). Further, StatusOr<T*> does not allow the
 // contained pointer to be nullptr.
 //
 // The primary use-case for StatusOr<T> is as the return value of a
@@ -72,8 +72,7 @@
 //
 //  StatusOr<Foo*> FooFactory::MakeNewFoo(int arg) {
 //    if (arg <= 0) {
-//      return ::util::Status(::util::error::INVALID_ARGUMENT,
-//                            "Arg must be positive");
+//      return InvalidArgumentError("Arg must be positive");
 //    } else {
 //      return new Foo(arg);
 //    }
@@ -100,7 +99,7 @@ class StatusOr {
   template<typename U> friend class StatusOr;
 
  public:
-  // Construct a new StatusOr with Status::UNKNOWN status
+  // Construct a new StatusOr with UnknownError() status.
   StatusOr();
 
   // Construct a new StatusOr with the given non-ok status. After calling
@@ -110,8 +109,8 @@ class StatusOr {
   // value, so it is convenient and sensible to be able to do 'return
   // Status()' when the return type is StatusOr<T>.
   //
-  // REQUIRES: status != Status::OK. This requirement is DCHECKed.
-  // In optimized builds, passing Status::OK here will have the effect
+  // REQUIRES: status != OkStatus(). This requirement is DCHECKed.
+  // In optimized builds, passing OkStatus() here will have the effect
   // of passing PosixErrorSpace::EINVAL as a fallback.
   StatusOr(const Status& status);  // NOLINT
 
@@ -143,7 +142,7 @@ class StatusOr {
   StatusOr& operator=(const StatusOr<U>& other);
 
   // Returns a reference to our status. If this contains a T, then
-  // returns Status::OK.
+  // returns OkStatus().
   const Status& status() const;
 
   // Returns this->status().ok()
@@ -188,15 +187,13 @@ struct StatusOrHelper::Specialize<T*> {
 
 }  // namespace internal
 
-template<typename T>
-inline StatusOr<T>::StatusOr()
-    : status_(util::Status::UNKNOWN) {
-}
+template <typename T>
+inline StatusOr<T>::StatusOr() : status_(util::UnknownError("")) {}
 
 template<typename T>
 inline StatusOr<T>::StatusOr(const Status& status) {
   if (status.ok()) {
-    status_ = Status(error::INTERNAL, "Status::OK is not a valid argument.");
+    status_ = util::InternalError("OkStatus() is not a valid argument.");
   } else {
     status_ = status;
   }
@@ -205,9 +202,9 @@ inline StatusOr<T>::StatusOr(const Status& status) {
 template<typename T>
 inline StatusOr<T>::StatusOr(const T& value) {
   if (internal::StatusOrHelper::Specialize<T>::IsValueNull(value)) {
-    status_ = Status(error::INTERNAL, "nullptr is not a valid argument.");
+    status_ = util::InternalError("nullptr is not a valid argument.");
   } else {
-    status_ = Status::OK;
+    status_ = util::OkStatus();
     value_ = value;
   }
 }

+ 18 - 18
src/google/protobuf/stubs/statusor_test.cc

@@ -71,13 +71,13 @@ class CopyNoAssign {
 TEST(StatusOr, TestDefaultCtor) {
   StatusOr<int> thing;
   EXPECT_FALSE(thing.ok());
-  EXPECT_EQ(Status::UNKNOWN, thing.status());
+  EXPECT_EQ(util::UnknownError(""), thing.status());
 }
 
 TEST(StatusOr, TestStatusCtor) {
-  StatusOr<int> thing(Status::CANCELLED);
+  StatusOr<int> thing(util::CancelledError(""));
   EXPECT_FALSE(thing.ok());
-  EXPECT_EQ(Status::CANCELLED, thing.status());
+  EXPECT_EQ(util::CancelledError(""), thing.status());
 }
 
 TEST(StatusOr, TestValueCtor) {
@@ -96,7 +96,7 @@ TEST(StatusOr, TestCopyCtorStatusOk) {
 }
 
 TEST(StatusOr, TestCopyCtorStatusNotOk) {
-  StatusOr<int> original(Status::CANCELLED);
+  StatusOr<int> original(util::CancelledError(""));
   StatusOr<int> copy(original);
   EXPECT_EQ(original.status(), copy.status());
 }
@@ -110,7 +110,7 @@ TEST(StatusOr, TestCopyCtorStatusOKConverting) {
 }
 
 TEST(StatusOr, TestCopyCtorStatusNotOkConverting) {
-  StatusOr<int>    original(Status::CANCELLED);
+  StatusOr<int> original(util::CancelledError(""));
   StatusOr<double> copy(original);
   EXPECT_EQ(original.status(), copy.status());
 }
@@ -125,7 +125,7 @@ TEST(StatusOr, TestAssignmentStatusOk) {
 }
 
 TEST(StatusOr, TestAssignmentStatusNotOk) {
-  StatusOr<int> source(Status::CANCELLED);
+  StatusOr<int> source(util::CancelledError(""));
   StatusOr<int> target;
   target = source;
   EXPECT_EQ(source.status(), target.status());
@@ -141,7 +141,7 @@ TEST(StatusOr, TestAssignmentStatusOKConverting) {
 }
 
 TEST(StatusOr, TestAssignmentStatusNotOkConverting) {
-  StatusOr<int>    source(Status::CANCELLED);
+  StatusOr<int> source(util::CancelledError(""));
   StatusOr<double> target;
   target = source;
   EXPECT_EQ(source.status(), target.status());
@@ -150,9 +150,9 @@ TEST(StatusOr, TestAssignmentStatusNotOkConverting) {
 TEST(StatusOr, TestStatus) {
   StatusOr<int> good(4);
   EXPECT_TRUE(good.ok());
-  StatusOr<int> bad(Status::CANCELLED);
+  StatusOr<int> bad(util::CancelledError(""));
   EXPECT_FALSE(bad.ok());
-  EXPECT_EQ(Status::CANCELLED, bad.status());
+  EXPECT_EQ(util::CancelledError(""), bad.status());
 }
 
 TEST(StatusOr, TestValue) {
@@ -170,13 +170,13 @@ TEST(StatusOr, TestValueConst) {
 TEST(StatusOr, TestPointerDefaultCtor) {
   StatusOr<int*> thing;
   EXPECT_FALSE(thing.ok());
-  EXPECT_EQ(Status::UNKNOWN, thing.status());
+  EXPECT_EQ(util::UnknownError(""), thing.status());
 }
 
 TEST(StatusOr, TestPointerStatusCtor) {
-  StatusOr<int*> thing(Status::CANCELLED);
+  StatusOr<int*> thing(util::CancelledError(""));
   EXPECT_FALSE(thing.ok());
-  EXPECT_EQ(Status::CANCELLED, thing.status());
+  EXPECT_EQ(util::CancelledError(""), thing.status());
 }
 
 TEST(StatusOr, TestPointerValueCtor) {
@@ -195,7 +195,7 @@ TEST(StatusOr, TestPointerCopyCtorStatusOk) {
 }
 
 TEST(StatusOr, TestPointerCopyCtorStatusNotOk) {
-  StatusOr<int*> original(Status::CANCELLED);
+  StatusOr<int*> original(util::CancelledError(""));
   StatusOr<int*> copy(original);
   EXPECT_EQ(original.status(), copy.status());
 }
@@ -210,7 +210,7 @@ TEST(StatusOr, TestPointerCopyCtorStatusOKConverting) {
 }
 
 TEST(StatusOr, TestPointerCopyCtorStatusNotOkConverting) {
-  StatusOr<Derived*> original(Status::CANCELLED);
+  StatusOr<Derived*> original(util::CancelledError(""));
   StatusOr<Base2*>   copy(original);
   EXPECT_EQ(original.status(), copy.status());
 }
@@ -225,7 +225,7 @@ TEST(StatusOr, TestPointerAssignmentStatusOk) {
 }
 
 TEST(StatusOr, TestPointerAssignmentStatusNotOk) {
-  StatusOr<int*> source(Status::CANCELLED);
+  StatusOr<int*> source(util::CancelledError(""));
   StatusOr<int*> target;
   target = source;
   EXPECT_EQ(source.status(), target.status());
@@ -242,7 +242,7 @@ TEST(StatusOr, TestPointerAssignmentStatusOKConverting) {
 }
 
 TEST(StatusOr, TestPointerAssignmentStatusNotOkConverting) {
-  StatusOr<Derived*> source(Status::CANCELLED);
+  StatusOr<Derived*> source(util::CancelledError(""));
   StatusOr<Base2*>   target;
   target = source;
   EXPECT_EQ(source.status(), target.status());
@@ -252,8 +252,8 @@ TEST(StatusOr, TestPointerStatus) {
   const int kI = 0;
   StatusOr<const int*> good(&kI);
   EXPECT_TRUE(good.ok());
-  StatusOr<const int*> bad(Status::CANCELLED);
-  EXPECT_EQ(Status::CANCELLED, bad.status());
+  StatusOr<const int*> bad(util::CancelledError(""));
+  EXPECT_EQ(util::CancelledError(""), bad.status());
 }
 
 TEST(StatusOr, TestPointerValue) {

+ 0 - 43
src/google/protobuf/stubs/stringpiece.h

@@ -426,49 +426,6 @@ inline bool operator>=(StringPiece x, StringPiece y) {
 // allow StringPiece to be logged
 extern std::ostream& operator<<(std::ostream& o, StringPiece piece);
 
-namespace internal {
-// StringPiece is not a POD and can not be used in an union (pre C++11). We
-// need a POD version of it.
-struct StringPiecePod {
-  // Create from a StringPiece.
-  static StringPiecePod CreateFromStringPiece(StringPiece str) {
-    StringPiecePod pod;
-    pod.data_ = str.data();
-    pod.size_ = str.size();
-    return pod;
-  }
-
-  // Cast to StringPiece.
-  operator StringPiece() const { return StringPiece(data_, size_); }
-
-  bool operator==(const char* value) const {
-    return StringPiece(data_, size_) == StringPiece(value);
-  }
-
-  char operator[](stringpiece_ssize_type i) const {
-    assert(0 <= i);
-    assert(i < size_);
-    return data_[i];
-  }
-
-  const char* data() const { return data_; }
-
-  stringpiece_ssize_type size() const {
-    return size_;
-  }
-
-  std::string ToString() const {
-    return std::string(data_, static_cast<size_t>(size_));
-  }
-
-  explicit operator std::string() const { return ToString(); }
-
- private:
-  const char* data_;
-  stringpiece_ssize_type size_;
-};
-
-}  // namespace internal
 }  // namespace protobuf
 }  // namespace google
 

+ 0 - 3
src/google/protobuf/stubs/strutil.h

@@ -664,9 +664,6 @@ struct PROTOBUF_EXPORT AlphaNum {
   AlphaNum(StringPiece str)
       : piece_data_(str.data()), piece_size_(str.size()) {}
 
-  AlphaNum(internal::StringPiecePod str)
-      : piece_data_(str.data()), piece_size_(str.size()) {}
-
   size_t size() const { return piece_size_; }
   const char *data() const { return piece_data_; }
 

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

@@ -13,7 +13,7 @@
 #error incompatible with your Protocol Buffer headers. Please update
 #error your headers.
 #endif
-#if 3015002 < PROTOBUF_MIN_PROTOC_VERSION
+#if 3015006 < 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.
@@ -69,7 +69,7 @@ class PROTOBUF_EXPORT Timestamp PROTOBUF_FINAL :
     public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.Timestamp) */ {
  public:
   inline Timestamp() : Timestamp(nullptr) {}
-  virtual ~Timestamp();
+  ~Timestamp() override;
   explicit constexpr Timestamp(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);
 
   Timestamp(const Timestamp& from);

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

@@ -13,7 +13,7 @@
 #error incompatible with your Protocol Buffer headers. Please update
 #error your headers.
 #endif
-#if 3015002 < PROTOBUF_MIN_PROTOC_VERSION
+#if 3015006 < 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.
@@ -182,7 +182,7 @@ class PROTOBUF_EXPORT Type PROTOBUF_FINAL :
     public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.Type) */ {
  public:
   inline Type() : Type(nullptr) {}
-  virtual ~Type();
+  ~Type() override;
   explicit constexpr Type(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);
 
   Type(const Type& from);
@@ -415,7 +415,7 @@ class PROTOBUF_EXPORT Field PROTOBUF_FINAL :
     public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.Field) */ {
  public:
   inline Field() : Field(nullptr) {}
-  virtual ~Field();
+  ~Field() override;
   explicit constexpr Field(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);
 
   Field(const Field& from);
@@ -772,7 +772,7 @@ class PROTOBUF_EXPORT Enum PROTOBUF_FINAL :
     public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.Enum) */ {
  public:
   inline Enum() : Enum(nullptr) {}
-  virtual ~Enum();
+  ~Enum() override;
   explicit constexpr Enum(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);
 
   Enum(const Enum& from);
@@ -979,7 +979,7 @@ class PROTOBUF_EXPORT EnumValue PROTOBUF_FINAL :
     public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.EnumValue) */ {
  public:
   inline EnumValue() : EnumValue(nullptr) {}
-  virtual ~EnumValue();
+  ~EnumValue() override;
   explicit constexpr EnumValue(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);
 
   EnumValue(const EnumValue& from);
@@ -1146,7 +1146,7 @@ class PROTOBUF_EXPORT Option PROTOBUF_FINAL :
     public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.Option) */ {
  public:
   inline Option() : Option(nullptr) {}
-  virtual ~Option();
+  ~Option() override;
   explicit constexpr Option(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);
 
   Option(const Option& from);

+ 4 - 4
src/google/protobuf/util/field_comparator.h

@@ -173,6 +173,10 @@ class PROTOBUF_EXPORT SimpleFieldComparator : public FieldComparator {
                               const Message& message1, const Message& message2,
                               const util::FieldContext* field_context);
 
+  // Returns FieldComparator::SAME if boolean_result is true and
+  // FieldComparator::DIFFERENT otherwise.
+  ComparisonResult ResultFromBoolean(bool boolean_result) const;
+
  private:
   // Defines the tolerance for floating point comparison (fraction and margin).
   struct Tolerance {
@@ -239,10 +243,6 @@ class PROTOBUF_EXPORT SimpleFieldComparator : public FieldComparator {
   template <typename T>
   bool CompareDoubleOrFloat(const FieldDescriptor& field, T value_1, T value_2);
 
-  // Returns FieldComparator::SAME if boolean_result is true and
-  // FieldComparator::DIFFERENT otherwise.
-  ComparisonResult ResultFromBoolean(bool boolean_result) const;
-
   FloatComparison float_comparison_;
 
   // If true, floats and doubles that are both NaN are considered to be

+ 16 - 20
src/google/protobuf/util/internal/datapiece.cc

@@ -48,25 +48,19 @@ namespace util {
 namespace converter {
 
 using util::Status;
-using util::error::Code;
 
 namespace {
 
-inline Status InvalidArgument(StringPiece value_str) {
-  return Status(util::error::INVALID_ARGUMENT, value_str);
-}
-
 template <typename To, typename From>
 util::StatusOr<To> ValidateNumberConversion(To after, From before) {
   if (after == before &&
       MathUtil::Sign<From>(before) == MathUtil::Sign<To>(after)) {
     return after;
   } else {
-    return InvalidArgument(std::is_integral<From>::value
-                               ? ValueAsString(before)
-                               : std::is_same<From, double>::value
-                                     ? DoubleAsString(before)
-                                     : FloatAsString(before));
+    return util::InvalidArgumentError(
+        std::is_integral<From>::value       ? ValueAsString(before)
+        : std::is_same<From, double>::value ? DoubleAsString(before)
+                                            : FloatAsString(before));
   }
 }
 
@@ -107,7 +101,7 @@ util::StatusOr<float> DoubleToFloat(double before) {
   } else if (before > std::numeric_limits<float>::max() ||
              before < -std::numeric_limits<float>::max()) {
     // Double value outside of the range of float.
-    return InvalidArgument(DoubleAsString(before));
+    return util::InvalidArgumentError(DoubleAsString(before));
   } else {
     return static_cast<float>(before);
   }
@@ -179,7 +173,7 @@ util::StatusOr<double> DataPiece::ToDouble() const {
     if (value.ok() && !std::isfinite(value.value())) {
       // safe_strtod converts out-of-range values to +inf/-inf, but we want
       // to report them as errors.
-      return InvalidArgument(StrCat("\"", str_, "\""));
+      return util::InvalidArgumentError(StrCat("\"", str_, "\""));
     } else {
       return value;
     }
@@ -209,7 +203,7 @@ util::StatusOr<bool> DataPiece::ToBool() const {
     case TYPE_STRING:
       return StringToNumber<bool>(safe_strtob);
     default:
-      return InvalidArgument(
+      return util::InvalidArgumentError(
           ValueAsStringOrDefault("Wrong type. Cannot convert to Bool."));
   }
 }
@@ -224,7 +218,7 @@ util::StatusOr<std::string> DataPiece::ToString() const {
       return base64;
     }
     default:
-      return InvalidArgument(
+      return util::InvalidArgumentError(
           ValueAsStringOrDefault("Cannot convert to string."));
   }
 }
@@ -265,11 +259,12 @@ util::StatusOr<std::string> DataPiece::ToBytes() const {
   if (type_ == TYPE_STRING) {
     std::string decoded;
     if (!DecodeBase64(str_, &decoded)) {
-      return InvalidArgument(ValueAsStringOrDefault("Invalid data in input."));
+      return util::InvalidArgumentError(
+          ValueAsStringOrDefault("Invalid data in input."));
     }
     return decoded;
   } else {
-    return InvalidArgument(ValueAsStringOrDefault(
+    return util::InvalidArgumentError(ValueAsStringOrDefault(
         "Wrong type. Only String or Bytes can be converted to Bytes."));
   }
 }
@@ -329,7 +324,7 @@ util::StatusOr<int> DataPiece::ToEnum(const google::protobuf::Enum* enum_type,
     // enum because we preserve unknown enum values as well.
     return ToInt32();
   }
-  return InvalidArgument(
+  return util::InvalidArgumentError(
       ValueAsStringOrDefault("Cannot find enum with given value."));
 }
 
@@ -349,7 +344,7 @@ util::StatusOr<To> DataPiece::GenericConvert() const {
     case TYPE_FLOAT:
       return NumberConvertAndCheck<To, float>(float_);
     default:  // TYPE_ENUM, TYPE_STRING, TYPE_CORD, TYPE_BOOL
-      return InvalidArgument(ValueAsStringOrDefault(
+      return util::InvalidArgumentError(ValueAsStringOrDefault(
           "Wrong type. Bool, Enum, String and Cord not supported in "
           "GenericConvert."));
   }
@@ -359,11 +354,12 @@ template <typename To>
 util::StatusOr<To> DataPiece::StringToNumber(bool (*func)(StringPiece,
                                                           To*)) const {
   if (str_.size() > 0 && (str_[0] == ' ' || str_[str_.size() - 1] == ' ')) {
-    return InvalidArgument(StrCat("\"", str_, "\""));
+    return util::InvalidArgumentError(StrCat("\"", str_, "\""));
   }
   To result;
   if (func(str_, &result)) return result;
-  return InvalidArgument(StrCat("\"", std::string(str_), "\""));
+  return util::InvalidArgumentError(
+      StrCat("\"", std::string(str_), "\""));
 }
 
 bool DataPiece::DecodeBase64(StringPiece src, std::string* dest) const {

+ 3 - 5
src/google/protobuf/util/internal/datapiece.h

@@ -94,12 +94,12 @@ class PROTOBUF_EXPORT DataPiece {
       : type_(TYPE_BOOL), bool_(value), use_strict_base64_decoding_(false) {}
   DataPiece(StringPiece value, bool use_strict_base64_decoding)
       : type_(TYPE_STRING),
-        str_(StringPiecePod::CreateFromStringPiece(value)),
+        str_(value),
         use_strict_base64_decoding_(use_strict_base64_decoding) {}
   // Constructor for bytes. The second parameter is not used.
   DataPiece(StringPiece value, bool dummy, bool use_strict_base64_decoding)
       : type_(TYPE_BYTES),
-        str_(StringPiecePod::CreateFromStringPiece(value)),
+        str_(value),
         use_strict_base64_decoding_(use_strict_base64_decoding) {}
 
   DataPiece(const DataPiece& r) : type_(r.type_) { InternalCopy(r); }
@@ -192,8 +192,6 @@ class PROTOBUF_EXPORT DataPiece {
   // Data type for this piece of data.
   Type type_;
 
-  typedef ::google::protobuf::internal::StringPiecePod StringPiecePod;
-
   // Stored piece of data.
   union {
     int32_t i32_;
@@ -203,7 +201,7 @@ class PROTOBUF_EXPORT DataPiece {
     double double_;
     float float_;
     bool bool_;
-    StringPiecePod str_;
+    StringPiece str_;
   };
 
   // Uses a stricter version of base64 decoding for byte fields.

+ 12 - 21
src/google/protobuf/util/internal/field_mask_utility.cc

@@ -134,11 +134,9 @@ util::Status DecodeCompactFieldMaskPaths(StringPiece paths,
         }
         // Un-escaped '"' must be followed with a ']'.
         if (i >= length - 1 || paths[i + 1] != ']') {
-          return util::Status(
-              util::error::INVALID_ARGUMENT,
-              StrCat(
-                  "Invalid FieldMask '", paths,
-                  "'. Map keys should be represented as [\"some_key\"]."));
+          return util::InvalidArgumentError(StrCat(
+              "Invalid FieldMask '", paths,
+              "'. Map keys should be represented as [\"some_key\"]."));
         }
         // The end of the map key ("\"]") has been found.
         in_map_key = false;
@@ -147,11 +145,9 @@ util::Status DecodeCompactFieldMaskPaths(StringPiece paths,
         // Checks whether the key ends at the end of a path segment.
         if (i < length - 1 && paths[i + 1] != '.' && paths[i + 1] != ',' &&
             paths[i + 1] != ')' && paths[i + 1] != '(') {
-          return util::Status(
-              util::error::INVALID_ARGUMENT,
-              StrCat(
-                  "Invalid FieldMask '", paths,
-                  "'. Map keys should be at the end of a path segment."));
+          return util::InvalidArgumentError(StrCat(
+              "Invalid FieldMask '", paths,
+              "'. Map keys should be at the end of a path segment."));
         }
         is_escaping = false;
         continue;
@@ -160,11 +156,9 @@ util::Status DecodeCompactFieldMaskPaths(StringPiece paths,
       // We are not in a map key, look for the start of one.
       if (paths[i] == '[') {
         if (i >= length - 1 || paths[i + 1] != '\"') {
-          return util::Status(
-              util::error::INVALID_ARGUMENT,
-              StrCat(
-                  "Invalid FieldMask '", paths,
-                  "'. Map keys should be represented as [\"some_key\"]."));
+          return util::InvalidArgumentError(StrCat(
+              "Invalid FieldMask '", paths,
+              "'. Map keys should be represented as [\"some_key\"]."));
         }
         // "[\"" starts a map key.
         in_map_key = true;
@@ -197,8 +191,7 @@ util::Status DecodeCompactFieldMaskPaths(StringPiece paths,
     // Removes the last prefix after seeing a ')'.
     if (i < length && paths[i] == ')') {
       if (prefix.empty()) {
-        return util::Status(
-            util::error::INVALID_ARGUMENT,
+        return util::InvalidArgumentError(
             StrCat("Invalid FieldMask '", paths,
                          "'. Cannot find matching '(' for all ')'."));
       }
@@ -207,14 +200,12 @@ util::Status DecodeCompactFieldMaskPaths(StringPiece paths,
     previous_position = i + 1;
   }
   if (in_map_key) {
-    return util::Status(
-        util::error::INVALID_ARGUMENT,
+    return util::InvalidArgumentError(
         StrCat("Invalid FieldMask '", paths,
                      "'. Cannot find matching ']' for all '['."));
   }
   if (!prefix.empty()) {
-    return util::Status(
-        util::error::INVALID_ARGUMENT,
+    return util::InvalidArgumentError(
         StrCat("Invalid FieldMask '", paths,
                      "'. Cannot find matching ')' for all '('."));
   }

+ 16 - 21
src/google/protobuf/util/internal/json_stream_parser.cc

@@ -302,14 +302,13 @@ util::Status JsonStreamParser::RunParser() {
         break;
 
       default:
-        result = util::Status(util::error::INTERNAL,
-                              StrCat("Unknown parse type: ", type));
+        result =
+            util::InternalError(StrCat("Unknown parse type: ", type));
         break;
     }
     if (!result.ok()) {
       // If we were cancelled, save our state and try again later.
-      if (!finishing_ &&
-          result == util::Status(util::error::CANCELLED, "")) {
+      if (!finishing_ && util::IsCancelled(result)) {
         stack_.push(type);
         // If we have a key we still need to render, make sure to save off the
         // contents in our own storage.
@@ -353,7 +352,7 @@ util::Status JsonStreamParser::ParseValue(TokenType type) {
       // don't know if the next char would be e, completing it, or something
       // else, making it invalid.
       if (!finishing_ && p_.length() < kKeywordFalse.length()) {
-        return util::Status(util::error::CANCELLED, "");
+        return util::CancelledError("");
       }
       return ReportFailure("Unexpected token.",
                            ParseErrorType::UNEXPECTED_TOKEN);
@@ -392,7 +391,7 @@ util::Status JsonStreamParser::ParseStringHelper() {
       // depending on if we expect more data later.
       if (p_.length() == 1) {
         if (!finishing_) {
-          return util::Status(util::error::CANCELLED, "");
+          return util::CancelledError("");
         }
         return ReportFailure("Closing quote expected in string.",
                              ParseErrorType::EXPECTED_CLOSING_QUOTE);
@@ -461,7 +460,7 @@ util::Status JsonStreamParser::ParseStringHelper() {
   }
   // If we didn't find the closing quote but we expect more data, cancel for now
   if (!finishing_) {
-    return util::Status(util::error::CANCELLED, "");
+    return util::CancelledError("");
   }
   // End of string reached without a closing quote, report an error.
   string_open_ = 0;
@@ -479,7 +478,7 @@ util::Status JsonStreamParser::ParseStringHelper() {
 util::Status JsonStreamParser::ParseUnicodeEscape() {
   if (p_.length() < kUnicodeEscapedLength) {
     if (!finishing_) {
-      return util::Status(util::error::CANCELLED, "");
+      return util::CancelledError("");
     }
     return ReportFailure("Illegal hex string.",
                          ParseErrorType::ILLEGAL_HEX_STRING);
@@ -498,7 +497,7 @@ util::Status JsonStreamParser::ParseUnicodeEscape() {
       code <= JsonEscaping::kMaxHighSurrogate) {
     if (p_.length() < 2 * kUnicodeEscapedLength) {
       if (!finishing_) {
-        return util::Status(util::error::CANCELLED, "");
+        return util::CancelledError("");
       }
       if (!coerce_to_utf8_) {
         return ReportFailure("Missing low surrogate.",
@@ -612,7 +611,7 @@ util::Status JsonStreamParser::ParseNumberHelper(NumberResult* result) {
   // If the entire input is a valid number, and we may have more content in the
   // future, we abort for now and resume when we know more.
   if (index == length && !finishing_) {
-    return util::Status(util::error::CANCELLED, "");
+    return util::CancelledError("");
   }
 
   // Create a string containing just the number, so we can use safe_strtoX
@@ -799,7 +798,7 @@ util::Status JsonStreamParser::ParseArrayValue(TokenType type) {
   // empty-null array value is relying on this ARRAY_MID token.
   stack_.push(ARRAY_MID);
   util::Status result = ParseValue(type);
-  if (result == util::Status(util::error::CANCELLED, "")) {
+  if (util::IsCancelled(result)) {
     // If we were cancelled, pop back off the ARRAY_MID so we don't try to
     // push it on again when we try over.
     stack_.pop();
@@ -874,10 +873,8 @@ util::Status JsonStreamParser::ReportFailure(StringPiece message,
   StringPiece segment(begin, end - begin);
   std::string location(p_start - begin, ' ');
   location.push_back('^');
-  auto status =
-      util::Status(util::error::INVALID_ARGUMENT,
-                   StrCat(message, "\n", segment, "\n", location));
-
+  auto status = util::InvalidArgumentError(
+      StrCat(message, "\n", segment, "\n", location));
   return status;
 }
 
@@ -885,7 +882,7 @@ util::Status JsonStreamParser::ReportUnknown(StringPiece message,
                                              ParseErrorType parse_code) {
   // If we aren't finishing the parse, cancel parsing and try later.
   if (!finishing_) {
-    return util::Status(util::error::CANCELLED, "");
+    return util::CancelledError("");
   }
   if (p_.empty()) {
     return ReportFailure(StrCat("Unexpected end of string. ", message),
@@ -897,10 +894,8 @@ util::Status JsonStreamParser::ReportUnknown(StringPiece message,
 util::Status JsonStreamParser::IncrementRecursionDepth(
     StringPiece key) const {
   if (++recursion_depth_ > max_recursion_depth_) {
-    return util::Status(
-        util::error::INVALID_ARGUMENT,
-        StrCat("Message too deep. Max recursion depth reached for key '",
-                     key, "'"));
+    return util::InvalidArgumentError(StrCat(
+        "Message too deep. Max recursion depth reached for key '", key, "'"));
   }
   return util::Status();
 }
@@ -940,7 +935,7 @@ util::Status JsonStreamParser::ParseKey() {
   // we can't know if the key was complete or not.
   if (!finishing_ && p_.empty()) {
     p_ = original;
-    return util::Status(util::error::CANCELLED, "");
+    return util::CancelledError("");
   }
   // Since we aren't using the key storage, clear it out.
   key_storage_.clear();

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

@@ -244,7 +244,7 @@ class PROTOBUF_EXPORT JsonStreamParser {
                              ParseErrorType parse_code);
 
   // Helper function to check recursion depth and increment it. It will return
-  // Status::OK if the current depth is allowed. Otherwise an error is returned.
+  // OkStatus() if the current depth is allowed. Otherwise an error is returned.
   // key is used for error reporting.
   util::Status IncrementRecursionDepth(StringPiece key) const;
 

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

@@ -138,8 +138,8 @@ class JsonStreamParserTest : public ::testing::Test {
       std::function<void(JsonStreamParser*)> setup = [](JsonStreamParser* p) {
       }) {
     util::Status result = RunTest(json, split, setup);
-    EXPECT_EQ(util::error::INVALID_ARGUMENT, result.code());
-    StringPiece error_message(result.error_message());
+    EXPECT_TRUE(util::IsInvalidArgument(result));
+    StringPiece error_message(result.message());
     EXPECT_EQ(error_prefix, error_message.substr(0, error_prefix.size()));
   }
 
@@ -149,8 +149,8 @@ class JsonStreamParserTest : public ::testing::Test {
       std::function<void(JsonStreamParser*)> setup = [](JsonStreamParser* p) {
       }) {
     util::Status result = RunTest(json, split, setup);
-    EXPECT_EQ(util::error::INVALID_ARGUMENT, result.code());
-    StringPiece error_message(result.error_message());
+    EXPECT_TRUE(util::IsInvalidArgument(result));
+    StringPiece error_message(result.message());
     EXPECT_EQ(error_prefix, error_message.substr(0, error_prefix.size()));
   }
 

+ 1 - 4
src/google/protobuf/util/internal/proto_writer.cc

@@ -55,8 +55,6 @@ namespace converter {
 
 using io::CodedOutputStream;
 using ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite;
-using util::error::INVALID_ARGUMENT;
-
 
 ProtoWriter::ProtoWriter(TypeResolver* type_resolver,
                          const google::protobuf::Type& type,
@@ -695,8 +693,7 @@ ProtoWriter* ProtoWriter::RenderPrimitiveField(
       break;
     }
     default:  // TYPE_GROUP, TYPE_MESSAGE, TYPE_UNKNOWN.
-      status = util::Status(util::error::INVALID_ARGUMENT,
-                            data.ValueAsStringOrDefault(""));
+      status = util::InvalidArgumentError(data.ValueAsStringOrDefault(""));
   }
 
   if (!status.ok()) {

+ 16 - 32
src/google/protobuf/util/internal/protostream_objectsource.cc

@@ -60,11 +60,8 @@
 namespace google {
 namespace protobuf {
 namespace util {
-namespace error {
-using util::error::Code;
-using util::error::INTERNAL;
-}  // namespace error
 namespace converter {
+
 using ::PROTOBUF_NAMESPACE_ID::internal::WireFormat;
 using ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite;
 
@@ -105,7 +102,7 @@ util::StatusOr<std::string> MapKeyDefaultValueAsString(
     case google::protobuf::Field::TYPE_STRING:
       return std::string();
     default:
-      return util::Status(util::error::INTERNAL, "Invalid map key type.");
+      return util::InternalError("Invalid map key type.");
   }
 }
 }  // namespace
@@ -285,8 +282,7 @@ util::StatusOr<uint32_t> ProtoStreamObjectSource::RenderMap(
           if (key_field == nullptr) {
             // The Type info for this map entry is incorrect. It should always
             // have a field named "key" and with field number 1.
-            return util::Status(util::error::INTERNAL,
-                                "Invalid map entry.");
+            return util::InternalError("Invalid map entry.");
           }
           ASSIGN_OR_RETURN(map_key, MapKeyDefaultValueAsString(*key_field));
         }
@@ -294,7 +290,7 @@ util::StatusOr<uint32_t> ProtoStreamObjectSource::RenderMap(
       } else {
         // The Type info for this map entry is incorrect. It should contain
         // exactly two fields with field number 1 and 2.
-        return util::Status(util::error::INTERNAL, "Invalid map entry.");
+        return util::InternalError("Invalid map entry.");
       }
     }
     stream_->PopLimit(old_limit);
@@ -321,15 +317,12 @@ util::Status ProtoStreamObjectSource::RenderTimestamp(
   int64_t seconds = p.first;
   int32_t nanos = p.second;
   if (seconds > kTimestampMaxSeconds || seconds < kTimestampMinSeconds) {
-    return util::Status(
-        util::error::INTERNAL,
-        StrCat("Timestamp seconds exceeds limit for field: ",
-                     field_name));
+    return util::InternalError(StrCat(
+        "Timestamp seconds exceeds limit for field: ", field_name));
   }
 
   if (nanos < 0 || nanos >= kNanosPerSecond) {
-    return util::Status(
-        util::error::INTERNAL,
+    return util::InternalError(
         StrCat("Timestamp nanos exceeds limit for field: ", field_name));
   }
 
@@ -346,22 +339,19 @@ util::Status ProtoStreamObjectSource::RenderDuration(
   int64_t seconds = p.first;
   int32_t nanos = p.second;
   if (seconds > kDurationMaxSeconds || seconds < kDurationMinSeconds) {
-    return util::Status(
-        util::error::INTERNAL,
+    return util::InternalError(
         StrCat("Duration seconds exceeds limit for field: ", field_name));
   }
 
   if (nanos <= -kNanosPerSecond || nanos >= kNanosPerSecond) {
-    return util::Status(
-        util::error::INTERNAL,
+    return util::InternalError(
         StrCat("Duration nanos exceeds limit for field: ", field_name));
   }
 
   std::string sign = "";
   if (seconds < 0) {
     if (nanos > 0) {
-      return util::Status(
-          util::error::INTERNAL,
+      return util::InternalError(
           StrCat("Duration nanos is non-negative, but seconds is "
                        "negative for field: ",
                        field_name));
@@ -614,8 +604,7 @@ util::Status ProtoStreamObjectSource::RenderAny(
   // If there is a value but no type, we cannot render it, so report an error.
   if (type_url.empty()) {
     // TODO(sven): Add an external message once those are ready.
-    return util::Status(util::error::INTERNAL,
-                        "Invalid Any, the type_url is missing.");
+    return util::InternalError("Invalid Any, the type_url is missing.");
   }
 
   util::StatusOr<const google::protobuf::Type*> resolved_type =
@@ -624,8 +613,7 @@ util::Status ProtoStreamObjectSource::RenderAny(
   if (!resolved_type.ok()) {
     // Convert into an internal error, since this means the backend gave us
     // an invalid response (missing or invalid type information).
-    return util::Status(util::error::INTERNAL,
-                        resolved_type.status().message());
+    return util::InternalError(resolved_type.status().message());
   }
   // nested_type cannot be null at this time.
   const google::protobuf::Type* nested_type = resolved_type.value();
@@ -662,8 +650,7 @@ util::Status ProtoStreamObjectSource::RenderFieldMask(
       }
     }
     if (paths_field_tag != tag) {
-      return util::Status(util::error::INTERNAL,
-                          "Invalid FieldMask, unexpected field.");
+      return util::InternalError("Invalid FieldMask, unexpected field.");
     }
     std::string str;
     os->stream_->ReadVarint32(&buffer32);  // string size.
@@ -747,8 +734,7 @@ util::Status ProtoStreamObjectSource::RenderField(
     const google::protobuf::Type* type =
         typeinfo_->GetTypeByTypeUrl(field->type_url());
     if (type == nullptr) {
-      return util::Status(
-          util::error::INTERNAL,
+      return util::InternalError(
           StrCat("Invalid configuration. Could not find the type: ",
                        field->type_url()));
     }
@@ -765,8 +751,7 @@ util::Status ProtoStreamObjectSource::RenderField(
     --recursion_depth_;
 
     if (!stream_->ConsumedEntireMessage()) {
-      return util::Status(
-          util::error::INVALID_ARGUMENT,
+      return util::InvalidArgumentError(
           "Nested protocol message not parsed in its entirety.");
     }
     stream_->PopLimit(old_limit);
@@ -1065,8 +1050,7 @@ std::pair<int64_t, int32_t> ProtoStreamObjectSource::ReadSecondsAndNanos(
 util::Status ProtoStreamObjectSource::IncrementRecursionDepth(
     StringPiece type_name, StringPiece field_name) const {
   if (++recursion_depth_ > max_recursion_depth_) {
-    return util::Status(
-        util::error::INVALID_ARGUMENT,
+    return util::InvalidArgumentError(
         StrCat("Message too deep. Max recursion depth reached for type '",
                      type_name, "', field '", field_name, "'"));
   }

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

@@ -287,7 +287,7 @@ class PROTOBUF_EXPORT ProtoStreamObjectSource : public ObjectSource {
       const google::protobuf::Type& type) const;
 
   // Helper function to check recursion depth and increment it. It will return
-  // Status::OK if the current depth is allowed. Otherwise an error is returned.
+  // OkStatus() if the current depth is allowed. Otherwise an error is returned.
   // type_name and field_name are used for error reporting.
   util::Status IncrementRecursionDepth(StringPiece type_name,
                                        StringPiece field_name) const;

+ 8 - 8
src/google/protobuf/util/internal/protostream_objectsource_test.cc

@@ -597,7 +597,7 @@ TEST_P(ProtostreamObjectSourceTest, CyclicMessageDepthTest) {
   }
 
   util::Status status = ExecuteTest(cyclic, Cyclic::descriptor());
-  EXPECT_EQ(util::error::INVALID_ARGUMENT, status.code());
+  EXPECT_TRUE(util::IsInvalidArgument(status));
 }
 
 class ProtostreamObjectSourceMapsTest : public ProtostreamObjectSourceTest {
@@ -943,7 +943,7 @@ TEST_P(ProtostreamObjectSourceAnysTest, MissingTypeUrlError) {
   ow_.StartObject("");
 
   util::Status status = ExecuteTest(out, AnyOut::descriptor());
-  EXPECT_EQ(util::error::INTERNAL, status.code());
+  EXPECT_TRUE(util::IsInternal(status));
 }
 
 TEST_P(ProtostreamObjectSourceAnysTest, UnknownTypeServiceError) {
@@ -959,7 +959,7 @@ TEST_P(ProtostreamObjectSourceAnysTest, UnknownTypeServiceError) {
   ow_.StartObject("");
 
   util::Status status = ExecuteTest(out, AnyOut::descriptor());
-  EXPECT_EQ(util::error::INTERNAL, status.code());
+  EXPECT_TRUE(util::IsInternal(status));
 }
 
 TEST_P(ProtostreamObjectSourceAnysTest, UnknownTypeError) {
@@ -975,7 +975,7 @@ TEST_P(ProtostreamObjectSourceAnysTest, UnknownTypeError) {
   ow_.StartObject("");
 
   util::Status status = ExecuteTest(out, AnyOut::descriptor());
-  EXPECT_EQ(util::error::INTERNAL, status.code());
+  EXPECT_TRUE(util::IsInternal(status));
 }
 
 class ProtostreamObjectSourceStructTest : public ProtostreamObjectSourceTest {
@@ -1108,7 +1108,7 @@ TEST_P(ProtostreamObjectSourceTimestampTest, InvalidTimestampBelowMinTest) {
   ow_.StartObject("");
 
   util::Status status = ExecuteTest(out, TimestampDuration::descriptor());
-  EXPECT_EQ(util::error::INTERNAL, status.code());
+  EXPECT_TRUE(util::IsInternal(status));
 }
 
 TEST_P(ProtostreamObjectSourceTimestampTest, InvalidTimestampAboveMaxTest) {
@@ -1119,7 +1119,7 @@ TEST_P(ProtostreamObjectSourceTimestampTest, InvalidTimestampAboveMaxTest) {
   ow_.StartObject("");
 
   util::Status status = ExecuteTest(out, TimestampDuration::descriptor());
-  EXPECT_EQ(util::error::INTERNAL, status.code());
+  EXPECT_TRUE(util::IsInternal(status));
 }
 
 TEST_P(ProtostreamObjectSourceTimestampTest, InvalidDurationBelowMinTest) {
@@ -1130,7 +1130,7 @@ TEST_P(ProtostreamObjectSourceTimestampTest, InvalidDurationBelowMinTest) {
   ow_.StartObject("");
 
   util::Status status = ExecuteTest(out, TimestampDuration::descriptor());
-  EXPECT_EQ(util::error::INTERNAL, status.code());
+  EXPECT_TRUE(util::IsInternal(status));
 }
 
 TEST_P(ProtostreamObjectSourceTimestampTest, InvalidDurationAboveMaxTest) {
@@ -1141,7 +1141,7 @@ TEST_P(ProtostreamObjectSourceTimestampTest, InvalidDurationAboveMaxTest) {
   ow_.StartObject("");
 
   util::Status status = ExecuteTest(out, TimestampDuration::descriptor());
-  EXPECT_EQ(util::error::INTERNAL, status.code());
+  EXPECT_TRUE(util::IsInternal(status));
 }
 
 TEST_P(ProtostreamObjectSourceTimestampTest, TimestampDurationDefaultValue) {

+ 22 - 25
src/google/protobuf/util/internal/protostream_objectwriter.cc

@@ -59,7 +59,6 @@ namespace converter {
 using ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite;
 using std::placeholders::_1;
 using util::Status;
-using util::error::INVALID_ARGUMENT;
 
 
 ProtoStreamObjectWriter::ProtoStreamObjectWriter(
@@ -144,14 +143,14 @@ Status GetNanosFromStringPiece(StringPiece s_nanos,
   // conversion to 'nanos', rather than a double, so that there is no
   // loss of precision.
   if (!s_nanos.empty() && !safe_strto32(s_nanos, &i_nanos)) {
-    return Status(util::error::INVALID_ARGUMENT, parse_failure_message);
+    return util::InvalidArgumentError(parse_failure_message);
   }
   if (i_nanos > kNanosPerSecond || i_nanos < 0) {
-    return Status(util::error::INVALID_ARGUMENT, exceeded_limit_message);
+    return util::InvalidArgumentError(exceeded_limit_message);
   }
   // s_nanos should only have digits. No whitespace.
   if (s_nanos.find_first_not_of("0123456789") != StringPiece::npos) {
-    return Status(util::error::INVALID_ARGUMENT, parse_failure_message);
+    return util::InvalidArgumentError(parse_failure_message);
   }
 
   if (i_nanos > 0) {
@@ -191,8 +190,7 @@ Status GetNanosFromStringPiece(StringPiece s_nanos,
         conversion = 1;
         break;
       default:
-        return Status(util::error::INVALID_ARGUMENT,
-                      exceeded_limit_message);
+        return util::InvalidArgumentError(exceeded_limit_message);
     }
     *nanos = i_nanos * conversion;
   }
@@ -1013,9 +1011,9 @@ Status ProtoStreamObjectWriter::RenderStructValue(ProtoStreamObjectWriter* ow,
       break;
     }
     default: {
-      return Status(util::error::INVALID_ARGUMENT,
-                    "Invalid struct data type. Only number, string, boolean or "
-                    "null values are supported.");
+      return util::InvalidArgumentError(
+          "Invalid struct data type. Only number, string, boolean or  null "
+          "values are supported.");
     }
   }
   ow->ProtoWriter::RenderDataPiece(struct_field_name, data);
@@ -1026,9 +1024,9 @@ Status ProtoStreamObjectWriter::RenderTimestamp(ProtoStreamObjectWriter* ow,
                                                 const DataPiece& data) {
   if (data.type() == DataPiece::TYPE_NULL) return Status();
   if (data.type() != DataPiece::TYPE_STRING) {
-    return Status(util::error::INVALID_ARGUMENT,
-                  StrCat("Invalid data type for timestamp, value is ",
-                               data.ValueAsStringOrDefault("")));
+    return util::InvalidArgumentError(
+        StrCat("Invalid data type for timestamp, value is ",
+                     data.ValueAsStringOrDefault("")));
   }
 
   StringPiece value(data.str());
@@ -1037,7 +1035,7 @@ Status ProtoStreamObjectWriter::RenderTimestamp(ProtoStreamObjectWriter* ow,
   int32 nanos;
   if (!::google::protobuf::internal::ParseTime(value.ToString(), &seconds,
                                                &nanos)) {
-    return Status(INVALID_ARGUMENT, StrCat("Invalid time format: ", value));
+    return util::InvalidArgumentError(StrCat("Invalid time format: ", value));
   }
 
 
@@ -1057,9 +1055,9 @@ Status ProtoStreamObjectWriter::RenderFieldMask(ProtoStreamObjectWriter* ow,
                                                 const DataPiece& data) {
   if (data.type() == DataPiece::TYPE_NULL) return Status();
   if (data.type() != DataPiece::TYPE_STRING) {
-    return Status(util::error::INVALID_ARGUMENT,
-                  StrCat("Invalid data type for field mask, value is ",
-                               data.ValueAsStringOrDefault("")));
+    return util::InvalidArgumentError(
+        StrCat("Invalid data type for field mask, value is ",
+                     data.ValueAsStringOrDefault("")));
   }
 
   // TODO(tsun): figure out how to do proto descriptor based snake case
@@ -1073,16 +1071,16 @@ Status ProtoStreamObjectWriter::RenderDuration(ProtoStreamObjectWriter* ow,
                                                const DataPiece& data) {
   if (data.type() == DataPiece::TYPE_NULL) return Status();
   if (data.type() != DataPiece::TYPE_STRING) {
-    return Status(util::error::INVALID_ARGUMENT,
-                  StrCat("Invalid data type for duration, value is ",
-                               data.ValueAsStringOrDefault("")));
+    return util::InvalidArgumentError(
+        StrCat("Invalid data type for duration, value is ",
+                     data.ValueAsStringOrDefault("")));
   }
 
   StringPiece value(data.str());
 
   if (!HasSuffixString(value, "s")) {
-    return Status(util::error::INVALID_ARGUMENT,
-                  "Illegal duration format; duration must end with 's'");
+    return util::InvalidArgumentError(
+        "Illegal duration format; duration must end with 's'");
   }
   value = value.substr(0, value.size() - 1);
   int sign = 1;
@@ -1095,8 +1093,8 @@ Status ProtoStreamObjectWriter::RenderDuration(ProtoStreamObjectWriter* ow,
   SplitSecondsAndNanos(value, &s_secs, &s_nanos);
   uint64_t unsigned_seconds;
   if (!safe_strtou64(s_secs, &unsigned_seconds)) {
-    return Status(util::error::INVALID_ARGUMENT,
-                  "Invalid duration format, failed to parse seconds");
+    return util::InvalidArgumentError(
+        "Invalid duration format, failed to parse seconds");
   }
 
   int32_t nanos = 0;
@@ -1111,8 +1109,7 @@ Status ProtoStreamObjectWriter::RenderDuration(ProtoStreamObjectWriter* ow,
   int64_t seconds = sign * unsigned_seconds;
   if (seconds > kDurationMaxSeconds || seconds < kDurationMinSeconds ||
       nanos <= -kNanosPerSecond || nanos >= kNanosPerSecond) {
-    return Status(util::error::INVALID_ARGUMENT,
-                  "Duration value exceeds limits");
+    return util::InvalidArgumentError("Duration value exceeds limits");
   }
 
   ow->ProtoWriter::RenderDataPiece("seconds", DataPiece(seconds));

+ 7 - 10
src/google/protobuf/util/json_util.cc

@@ -140,25 +140,22 @@ class StatusErrorListener : public converter::ErrorListener {
     if (!loc_string.empty()) {
       loc_string.append(" ");
     }
-    status_ =
-        util::Status(util::error::INVALID_ARGUMENT,
-                     StrCat(loc_string, unknown_name, ": ", message));
+    status_ = util::InvalidArgumentError(
+        StrCat(loc_string, unknown_name, ": ", message));
   }
 
   void InvalidValue(const converter::LocationTrackerInterface& loc,
                     StringPiece type_name,
                     StringPiece value) override {
-    status_ = util::Status(
-        util::error::INVALID_ARGUMENT,
+    status_ = util::InvalidArgumentError(
         StrCat(GetLocString(loc), ": invalid value ", std::string(value),
                      " for type ", std::string(type_name)));
   }
 
   void MissingField(const converter::LocationTrackerInterface& loc,
                     StringPiece missing_name) override {
-    status_ = util::Status(util::error::INVALID_ARGUMENT,
-                           StrCat(GetLocString(loc), ": missing field ",
-                                        std::string(missing_name)));
+    status_ = util::InvalidArgumentError(StrCat(
+        GetLocString(loc), ": missing field ", std::string(missing_name)));
   }
 
  private:
@@ -271,8 +268,8 @@ util::Status JsonStringToMessage(StringPiece input, Message* message,
   util::Status result = JsonToBinaryString(resolver, GetTypeUrl(*message),
                                            input, &binary, options);
   if (result.ok() && !message->ParseFromString(binary)) {
-    result = util::Status(util::error::INVALID_ARGUMENT,
-                          "JSON transcoder produced invalid protobuf output.");
+    result = util::InvalidArgumentError(
+        "JSON transcoder produced invalid protobuf output.");
   }
   if (pool != DescriptorPool::generated_pool()) {
     delete resolver;

+ 1 - 2
src/google/protobuf/util/json_util_test.cc

@@ -633,8 +633,7 @@ TEST_F(JsonUtilTest, TestWrongJsonInput) {
   delete resolver;
 
   EXPECT_FALSE(result_status.ok());
-  EXPECT_EQ(result_status.code(),
-            util::error::INVALID_ARGUMENT);
+  EXPECT_TRUE(util::IsInvalidArgument(result_status));
 }
 
 TEST_F(JsonUtilTest, HtmlEscape) {

+ 5 - 9
src/google/protobuf/util/type_resolver_util.cc

@@ -64,9 +64,6 @@ using google::protobuf::Type;
 using google::protobuf::UInt32Value;
 using google::protobuf::UInt64Value;
 
-using util::error::INVALID_ARGUMENT;
-using util::error::NOT_FOUND;
-
 class DescriptorPoolTypeResolver : public TypeResolver {
  public:
   DescriptorPoolTypeResolver(const std::string& url_prefix,
@@ -83,8 +80,8 @@ class DescriptorPoolTypeResolver : public TypeResolver {
 
     const Descriptor* descriptor = pool_->FindMessageTypeByName(type_name);
     if (descriptor == NULL) {
-      return util::Status(util::error::NOT_FOUND,
-                          "Invalid type URL, unknown type: " + type_name);
+      return util::NotFoundError("Invalid type URL, unknown type: " +
+                                 type_name);
     }
     ConvertDescriptor(descriptor, type);
     return util::Status();
@@ -100,8 +97,8 @@ class DescriptorPoolTypeResolver : public TypeResolver {
 
     const EnumDescriptor* descriptor = pool_->FindEnumTypeByName(type_name);
     if (descriptor == NULL) {
-      return util::Status(util::error::NOT_FOUND,
-                          "Invalid type URL, unknown type: " + type_name);
+      return util::InvalidArgumentError("Invalid type URL, unknown type: " +
+                                        type_name);
     }
     ConvertEnumDescriptor(descriptor, enum_type);
     return util::Status();
@@ -309,8 +306,7 @@ class DescriptorPoolTypeResolver : public TypeResolver {
   util::Status ParseTypeUrl(const std::string& type_url,
                             std::string* type_name) {
     if (type_url.substr(0, url_prefix_.size() + 1) != url_prefix_ + "/") {
-      return util::Status(
-          util::error::INVALID_ARGUMENT,
+      return util::InvalidArgumentError(
           StrCat("Invalid type URL, type URLs must be of the form '",
                        url_prefix_, "/<typename>', got: ", type_url));
     }

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

@@ -13,7 +13,7 @@
 #error incompatible with your Protocol Buffer headers. Please update
 #error your headers.
 #endif
-#if 3015002 < PROTOBUF_MIN_PROTOC_VERSION
+#if 3015006 < 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.
@@ -101,7 +101,7 @@ class PROTOBUF_EXPORT DoubleValue PROTOBUF_FINAL :
     public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.DoubleValue) */ {
  public:
   inline DoubleValue() : DoubleValue(nullptr) {}
-  virtual ~DoubleValue();
+  ~DoubleValue() override;
   explicit constexpr DoubleValue(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);
 
   DoubleValue(const DoubleValue& from);
@@ -232,7 +232,7 @@ class PROTOBUF_EXPORT FloatValue PROTOBUF_FINAL :
     public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.FloatValue) */ {
  public:
   inline FloatValue() : FloatValue(nullptr) {}
-  virtual ~FloatValue();
+  ~FloatValue() override;
   explicit constexpr FloatValue(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);
 
   FloatValue(const FloatValue& from);
@@ -363,7 +363,7 @@ class PROTOBUF_EXPORT Int64Value PROTOBUF_FINAL :
     public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.Int64Value) */ {
  public:
   inline Int64Value() : Int64Value(nullptr) {}
-  virtual ~Int64Value();
+  ~Int64Value() override;
   explicit constexpr Int64Value(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);
 
   Int64Value(const Int64Value& from);
@@ -494,7 +494,7 @@ class PROTOBUF_EXPORT UInt64Value PROTOBUF_FINAL :
     public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.UInt64Value) */ {
  public:
   inline UInt64Value() : UInt64Value(nullptr) {}
-  virtual ~UInt64Value();
+  ~UInt64Value() override;
   explicit constexpr UInt64Value(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);
 
   UInt64Value(const UInt64Value& from);
@@ -625,7 +625,7 @@ class PROTOBUF_EXPORT Int32Value PROTOBUF_FINAL :
     public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.Int32Value) */ {
  public:
   inline Int32Value() : Int32Value(nullptr) {}
-  virtual ~Int32Value();
+  ~Int32Value() override;
   explicit constexpr Int32Value(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);
 
   Int32Value(const Int32Value& from);
@@ -756,7 +756,7 @@ class PROTOBUF_EXPORT UInt32Value PROTOBUF_FINAL :
     public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.UInt32Value) */ {
  public:
   inline UInt32Value() : UInt32Value(nullptr) {}
-  virtual ~UInt32Value();
+  ~UInt32Value() override;
   explicit constexpr UInt32Value(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);
 
   UInt32Value(const UInt32Value& from);
@@ -887,7 +887,7 @@ class PROTOBUF_EXPORT BoolValue PROTOBUF_FINAL :
     public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.BoolValue) */ {
  public:
   inline BoolValue() : BoolValue(nullptr) {}
-  virtual ~BoolValue();
+  ~BoolValue() override;
   explicit constexpr BoolValue(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);
 
   BoolValue(const BoolValue& from);
@@ -1018,7 +1018,7 @@ class PROTOBUF_EXPORT StringValue PROTOBUF_FINAL :
     public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.StringValue) */ {
  public:
   inline StringValue() : StringValue(nullptr) {}
-  virtual ~StringValue();
+  ~StringValue() override;
   explicit constexpr StringValue(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);
 
   StringValue(const StringValue& from);
@@ -1154,7 +1154,7 @@ class PROTOBUF_EXPORT BytesValue PROTOBUF_FINAL :
     public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.BytesValue) */ {
  public:
   inline BytesValue() : BytesValue(nullptr) {}
-  virtual ~BytesValue();
+  ~BytesValue() override;
   explicit constexpr BytesValue(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);
 
   BytesValue(const BytesValue& from);