Merge tag 'refs/tags/sync-piper' into sync-stage
diff --git a/Protobuf-C++.podspec b/Protobuf-C++.podspec
index fbd37b2..13adedd 100644
--- a/Protobuf-C++.podspec
+++ b/Protobuf-C++.podspec
@@ -1,6 +1,6 @@
 Pod::Spec.new do |s|
   s.name     = 'Protobuf-C++'
-  s.version  = '3.15.6'
+  s.version  = '3.15.8'
   s.summary  = 'Protocol Buffers v3 runtime library for C++.'
   s.homepage = 'https://github.com/google/protobuf'
   s.license  = '3-Clause BSD License'
diff --git a/benchmarks/download_data.sh b/benchmarks/download_data.sh
deleted file mode 100755
index fa0729e..0000000
--- a/benchmarks/download_data.sh
+++ /dev/null
@@ -1,5 +0,0 @@
-#! /bin/sh
-
-curl -O https://storage.googleapis.com/protobuf_opensource_benchmark_data/datasets.tar.gz
-tar -zvxf datasets.tar.gz
-
diff --git a/build_files_updated_unittest.sh b/build_files_updated_unittest.sh
index c863071..87541c3 100755
--- a/build_files_updated_unittest.sh
+++ b/build_files_updated_unittest.sh
@@ -58,5 +58,5 @@
 
 # Test whether there are any differences
 for file in ${generated_files[@]}; do
-  diff "${golden_dir}/${file}" "${test_dir}/${file}"
+  diff -du "${golden_dir}/${file}" "${test_dir}/${file}"
 done
diff --git a/configure.ac b/configure.ac
index 0e84cc0..2b575ef 100644
--- a/configure.ac
+++ b/configure.ac
@@ -17,7 +17,7 @@
 # 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.6],[protobuf@googlegroups.com],[protobuf])
+AC_INIT([Protocol Buffers],[3.15.8],[protobuf@googlegroups.com],[protobuf])
 
 AM_MAINTAINER_MODE([enable])
 
diff --git a/js/package.json b/js/package.json
index 5971046..19812c0 100644
--- a/js/package.json
+++ b/js/package.json
@@ -1,6 +1,6 @@
 {
   "name": "google-protobuf",
-  "version": "3.15.6",
+  "version": "3.15.8",
   "description": "Protocol Buffers for JavaScript",
   "main": "google-protobuf.js",
   "files": [
diff --git a/python/google/protobuf/__init__.py b/python/google/protobuf/__init__.py
index b356d67..4607bec 100644
--- a/python/google/protobuf/__init__.py
+++ b/python/google/protobuf/__init__.py
@@ -30,4 +30,4 @@
 
 # Copyright 2007 Google Inc. All Rights Reserved.
 
-__version__ = '3.15.6'
+__version__ = '3.15.8'
diff --git a/python/google/protobuf/descriptor.py b/python/google/protobuf/descriptor.py
index 190b895..c8f7b41 100644
--- a/python/google/protobuf/descriptor.py
+++ b/python/google/protobuf/descriptor.py
@@ -912,6 +912,24 @@
     self.containing_service = containing_service
     self.input_type = input_type
     self.output_type = output_type
+  
+  def CopyToProto(self, proto):
+    """Copies this to a descriptor_pb2.MethodDescriptorProto.
+
+    Args:
+      proto (descriptor_pb2.MethodDescriptorProto): An empty descriptor proto.
+
+    Raises:
+      Error: If self couldn't be serialized, due to too few constructor
+        arguments.
+    """
+    if self.containing_service is not None:
+      from google.protobuf import descriptor_pb2
+      service_proto = descriptor_pb2.ServiceDescriptorProto()
+      self.containing_service.CopyToProto(service_proto)
+      proto.CopyFrom(service_proto.method[self.index])
+    else:
+      raise Error('Descriptor does not contain a service.')
 
 
 class FileDescriptor(DescriptorBase):
diff --git a/python/google/protobuf/internal/descriptor_test.py b/python/google/protobuf/internal/descriptor_test.py
index 5e3b0a9..4fc8049 100755
--- a/python/google/protobuf/internal/descriptor_test.py
+++ b/python/google/protobuf/internal/descriptor_test.py
@@ -907,10 +907,6 @@
         descriptor_pb2.ServiceDescriptorProto,
         TEST_SERVICE_ASCII)
 
-  @unittest.skipIf(
-      api_implementation.Type() == 'python',
-      'It is not implemented in python.')
-  # TODO(jieluo): Add support for pure python or remove in c extension.
   def testCopyToProto_MethodDescriptor(self):
     expected_ascii = """
       name: 'Foo'
diff --git a/python/setup.py b/python/setup.py
index aab240a..696bde2 100755
--- a/python/setup.py
+++ b/python/setup.py
@@ -18,6 +18,7 @@
 
 from distutils.command.build_py import build_py as _build_py
 from distutils.command.clean import clean as _clean
+from distutils.command.build_ext import build_ext as _build_ext
 from distutils.spawn import find_executable
 
 # Find the Protocol Compiler.
@@ -157,6 +158,22 @@
             if not any(fnmatch.fnmatchcase(fil, pat=pat) for pat in exclude)]
 
 
+class build_ext(_build_ext):
+  def get_ext_filename(self, ext_name):
+      # since python3.5, python extensions' shared libraries use a suffix that corresponds to the value
+      # of sysconfig.get_config_var('EXT_SUFFIX') and contains info about the architecture the library targets.
+      # E.g. on x64 linux the suffix is ".cpython-XYZ-x86_64-linux-gnu.so"
+      # When crosscompiling python wheels, we need to be able to override this suffix
+      # so that the resulting file name matches the target architecture and we end up with a well-formed
+      # wheel.
+      filename = _build_ext.get_ext_filename(self, ext_name)
+      orig_ext_suffix = sysconfig.get_config_var("EXT_SUFFIX")
+      new_ext_suffix = os.getenv("PROTOCOL_BUFFERS_OVERRIDE_EXT_SUFFIX")
+      if new_ext_suffix and filename.endswith(orig_ext_suffix):
+        filename = filename[:-len(orig_ext_suffix)] + new_ext_suffix
+      return filename
+
+
 class test_conformance(_build_py):
   target = 'test_python'
   def run(self):
@@ -291,6 +308,7 @@
       cmdclass={
           'clean': clean,
           'build_py': build_py,
+          'build_ext': build_ext,
           'test_conformance': test_conformance,
       },
       install_requires=install_requires,
diff --git a/src/Makefile.am b/src/Makefile.am
index c2b25c1..18b1a43 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -18,7 +18,7 @@
 PTHREAD_DEF =
 endif
 
-PROTOBUF_VERSION = 26:6:0
+PROTOBUF_VERSION = 26:8:0
 
 if GCC
 # Turn on all warnings except for sign comparison (we ignore sign comparison
diff --git a/src/google/protobuf/any.pb.h b/src/google/protobuf/any.pb.h
index c405423..33419bc 100644
--- a/src/google/protobuf/any.pb.h
+++ b/src/google/protobuf/any.pb.h
@@ -13,7 +13,7 @@
 #error incompatible with your Protocol Buffer headers. Please update
 #error your headers.
 #endif
-#if 3015006 < PROTOBUF_MIN_PROTOC_VERSION
+#if 3015008 < 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.
diff --git a/src/google/protobuf/api.pb.h b/src/google/protobuf/api.pb.h
index 052fb57..15ee4c1 100644
--- a/src/google/protobuf/api.pb.h
+++ b/src/google/protobuf/api.pb.h
@@ -13,7 +13,7 @@
 #error incompatible with your Protocol Buffer headers. Please update
 #error your headers.
 #endif
-#if 3015006 < PROTOBUF_MIN_PROTOC_VERSION
+#if 3015008 < 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.
diff --git a/src/google/protobuf/compiler/cpp/cpp_helpers.cc b/src/google/protobuf/compiler/cpp/cpp_helpers.cc
index faaf036..fbca72c 100644
--- a/src/google/protobuf/compiler/cpp/cpp_helpers.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_helpers.cc
@@ -1022,13 +1022,13 @@
                                const Options& options) {
   if (field->file()->syntax() == FileDescriptor::SYNTAX_PROTO3 &&
       FieldEnforceUtf8(field, options)) {
-    return STRICT;
+    return Utf8CheckMode::kStrict;
   } else if (GetOptimizeFor(field->file(), options) !=
                  FileOptions::LITE_RUNTIME &&
              FileUtf8Verification(field->file(), options)) {
-    return VERIFY;
+    return Utf8CheckMode::kVerify;
   } else {
-    return NONE;
+    return Utf8CheckMode::kNone;
   }
 }
 
@@ -1039,7 +1039,7 @@
                                   const char* verify_function,
                                   const Formatter& format) {
   switch (GetUtf8CheckMode(field, options)) {
-    case STRICT: {
+    case Utf8CheckMode::kStrict: {
       if (for_parse) {
         format("DO_(");
       }
@@ -1059,7 +1059,7 @@
       format.Outdent();
       break;
     }
-    case VERIFY: {
+    case Utf8CheckMode::kVerify: {
       format("::$proto_ns$::internal::WireFormat::$1$(\n", verify_function);
       format.Indent();
       format(parameters);
@@ -1072,7 +1072,7 @@
       format.Outdent();
       break;
     }
-    case NONE:
+    case Utf8CheckMode::kNone:
       break;
   }
 }
diff --git a/src/google/protobuf/compiler/cpp/cpp_helpers.h b/src/google/protobuf/compiler/cpp/cpp_helpers.h
index 468bdd9..5fa019d 100644
--- a/src/google/protobuf/compiler/cpp/cpp_helpers.h
+++ b/src/google/protobuf/compiler/cpp/cpp_helpers.h
@@ -774,10 +774,10 @@
   std::vector<std::string> name_stack_;
 };
 
-enum Utf8CheckMode {
-  STRICT = 0,  // Parsing will fail if non UTF-8 data is in string fields.
-  VERIFY = 1,  // Only log an error but parsing will succeed.
-  NONE = 2,    // No UTF-8 check.
+enum class Utf8CheckMode {
+  kStrict = 0,  // Parsing will fail if non UTF-8 data is in string fields.
+  kVerify = 1,  // Only log an error but parsing will succeed.
+  kNone = 2,    // No UTF-8 check.
 };
 
 Utf8CheckMode GetUtf8CheckMode(const FieldDescriptor* field,
diff --git a/src/google/protobuf/compiler/cpp/cpp_message.cc b/src/google/protobuf/compiler/cpp/cpp_message.cc
index 9886d19..f2d1aab 100644
--- a/src/google/protobuf/compiler/cpp/cpp_message.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_message.cc
@@ -1018,8 +1018,8 @@
         "$classname$*>(&_$classname$_default_instance_); }\n");
     auto utf8_check = GetUtf8CheckMode(descriptor_->field(0), options_);
     if (descriptor_->field(0)->type() == FieldDescriptor::TYPE_STRING &&
-        utf8_check != NONE) {
-      if (utf8_check == STRICT) {
+        utf8_check != Utf8CheckMode::kNone) {
+      if (utf8_check == Utf8CheckMode::kStrict) {
         format(
             "  static bool ValidateKey(std::string* s) {\n"
             "    return ::$proto_ns$::internal::WireFormatLite::"
@@ -1028,7 +1028,7 @@
             " }\n",
             descriptor_->field(0)->full_name());
       } else {
-        GOOGLE_CHECK_EQ(utf8_check, VERIFY);
+        GOOGLE_CHECK_EQ(utf8_check, Utf8CheckMode::kVerify);
         format(
             "  static bool ValidateKey(std::string* s) {\n"
             "#ifndef NDEBUG\n"
@@ -1047,8 +1047,8 @@
       format("  static bool ValidateKey(void*) { return true; }\n");
     }
     if (descriptor_->field(1)->type() == FieldDescriptor::TYPE_STRING &&
-        utf8_check != NONE) {
-      if (utf8_check == STRICT) {
+        utf8_check != Utf8CheckMode::kNone) {
+      if (utf8_check == Utf8CheckMode::kStrict) {
         format(
             "  static bool ValidateValue(std::string* s) {\n"
             "    return ::$proto_ns$::internal::WireFormatLite::"
@@ -1057,7 +1057,7 @@
             " }\n",
             descriptor_->field(1)->full_name());
       } else {
-        GOOGLE_CHECK_EQ(utf8_check, VERIFY);
+        GOOGLE_CHECK_EQ(utf8_check, Utf8CheckMode::kVerify);
         format(
             "  static bool ValidateValue(std::string* s) {\n"
             "#ifndef NDEBUG\n"
diff --git a/src/google/protobuf/compiler/cpp/cpp_parse_function_generator.cc b/src/google/protobuf/compiler/cpp/cpp_parse_function_generator.cc
index 4e26a95..41be0b5 100644
--- a/src/google/protobuf/compiler/cpp/cpp_parse_function_generator.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_parse_function_generator.cc
@@ -187,12 +187,12 @@
     if (!check_utf8) return;  // return if this is a bytes field
     auto level = GetUtf8CheckMode(field, options_);
     switch (level) {
-      case NONE:
+      case Utf8CheckMode::kNone:
         return;
-      case VERIFY:
+      case Utf8CheckMode::kVerify:
         format_("#ifndef NDEBUG\n");
         break;
-      case STRICT:
+      case Utf8CheckMode::kStrict:
         format_("CHK_(");
         break;
     }
@@ -203,14 +203,14 @@
     }
     format_("$pi_ns$::VerifyUTF8(str, $1$)", field_name);
     switch (level) {
-      case NONE:
+      case Utf8CheckMode::kNone:
         return;
-      case VERIFY:
+      case Utf8CheckMode::kVerify:
         format_(
             ";\n"
             "#endif  // !NDEBUG\n");
         break;
-      case STRICT:
+      case Utf8CheckMode::kStrict:
         format_(");\n");
         break;
     }
diff --git a/src/google/protobuf/compiler/plugin.pb.h b/src/google/protobuf/compiler/plugin.pb.h
index ed8746b..67eeabb 100644
--- a/src/google/protobuf/compiler/plugin.pb.h
+++ b/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 3015006 < PROTOBUF_MIN_PROTOC_VERSION
+#if 3015008 < 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.
diff --git a/src/google/protobuf/descriptor.pb.h b/src/google/protobuf/descriptor.pb.h
index 880d2da..c3b7ed2 100644
--- a/src/google/protobuf/descriptor.pb.h
+++ b/src/google/protobuf/descriptor.pb.h
@@ -13,7 +13,7 @@
 #error incompatible with your Protocol Buffer headers. Please update
 #error your headers.
 #endif
-#if 3015006 < PROTOBUF_MIN_PROTOC_VERSION
+#if 3015008 < 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.
diff --git a/src/google/protobuf/duration.pb.h b/src/google/protobuf/duration.pb.h
index b59edab..1ee55f6 100644
--- a/src/google/protobuf/duration.pb.h
+++ b/src/google/protobuf/duration.pb.h
@@ -13,7 +13,7 @@
 #error incompatible with your Protocol Buffer headers. Please update
 #error your headers.
 #endif
-#if 3015006 < PROTOBUF_MIN_PROTOC_VERSION
+#if 3015008 < 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.
diff --git a/src/google/protobuf/empty.pb.h b/src/google/protobuf/empty.pb.h
index 9ad0eea..ade3660 100644
--- a/src/google/protobuf/empty.pb.h
+++ b/src/google/protobuf/empty.pb.h
@@ -13,7 +13,7 @@
 #error incompatible with your Protocol Buffer headers. Please update
 #error your headers.
 #endif
-#if 3015006 < PROTOBUF_MIN_PROTOC_VERSION
+#if 3015008 < 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.
diff --git a/src/google/protobuf/field_mask.pb.h b/src/google/protobuf/field_mask.pb.h
index e9a5126..5d8ec48 100644
--- a/src/google/protobuf/field_mask.pb.h
+++ b/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 3015006 < PROTOBUF_MIN_PROTOC_VERSION
+#if 3015008 < 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.
diff --git a/src/google/protobuf/port_def.inc b/src/google/protobuf/port_def.inc
index 7a2a975..8a64749 100644
--- a/src/google/protobuf/port_def.inc
+++ b/src/google/protobuf/port_def.inc
@@ -345,7 +345,7 @@
 #endif
 
 
-#define PROTOBUF_VERSION 3015006
+#define PROTOBUF_VERSION 3015008
 #define PROTOBUF_MIN_HEADER_VERSION_FOR_PROTOC 3015000
 #define PROTOBUF_MIN_PROTOC_VERSION 3015000
 #define PROTOBUF_VERSION_SUFFIX ""
@@ -444,6 +444,8 @@
 #ifdef _MSC_VER
 #pragma push_macro("CREATE_NEW")
 #undef CREATE_NEW
+#pragma push_macro("DELETE")
+#undef DELETE
 #pragma push_macro("DOUBLE_CLICK")
 #undef DOUBLE_CLICK
 #pragma push_macro("ERROR")
@@ -489,7 +491,7 @@
 #endif  // _MSC_VER
 
 #if defined(__clang__) || defined(__GNUC__) || defined(_MSC_VER)
-// Don't let Objective-C Macros interfere with proto identifiers with the same 
+// Don't let Objective-C Macros interfere with proto identifiers with the same
 // name.
 #pragma push_macro("DEBUG")
 #undef DEBUG
diff --git a/src/google/protobuf/port_undef.inc b/src/google/protobuf/port_undef.inc
index 5d95a90..e40ac0d 100644
--- a/src/google/protobuf/port_undef.inc
+++ b/src/google/protobuf/port_undef.inc
@@ -89,6 +89,7 @@
 // Restore macro that may have been #undef'd in port_def.inc.
 #ifdef _MSC_VER
 #pragma pop_macro("CREATE_NEW")
+#pragma pop_macro("DELETE")
 #pragma pop_macro("DOUBLE_CLICK")
 #pragma pop_macro("ERROR")
 #pragma pop_macro("ERROR_BUSY")
diff --git a/src/google/protobuf/source_context.pb.h b/src/google/protobuf/source_context.pb.h
index a763ff9..94e5170 100644
--- a/src/google/protobuf/source_context.pb.h
+++ b/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 3015006 < PROTOBUF_MIN_PROTOC_VERSION
+#if 3015008 < 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.
diff --git a/src/google/protobuf/struct.pb.h b/src/google/protobuf/struct.pb.h
index 936ded8..a6f5e78 100644
--- a/src/google/protobuf/struct.pb.h
+++ b/src/google/protobuf/struct.pb.h
@@ -13,7 +13,7 @@
 #error incompatible with your Protocol Buffer headers. Please update
 #error your headers.
 #endif
-#if 3015006 < PROTOBUF_MIN_PROTOC_VERSION
+#if 3015008 < 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.
diff --git a/src/google/protobuf/stubs/bytestream.cc b/src/google/protobuf/stubs/bytestream.cc
index a0f298e..980d6f6 100644
--- a/src/google/protobuf/stubs/bytestream.cc
+++ b/src/google/protobuf/stubs/bytestream.cc
@@ -173,12 +173,8 @@
 }
 
 StringPiece LimitByteSource::Peek() {
-  StringPiece piece(source_->Peek());
-  if (piece.size() > limit_) {
-    piece.set(piece.data(), limit_);
-  }
-
-  return piece;
+  StringPiece piece = source_->Peek();
+  return StringPiece(piece.data(), std::min(piece.size(), limit_));
 }
 
 void LimitByteSource::Skip(size_t n) {
diff --git a/src/google/protobuf/stubs/casts.h b/src/google/protobuf/stubs/casts.h
index d8a49ce..ad29dac 100644
--- a/src/google/protobuf/stubs/casts.h
+++ b/src/google/protobuf/stubs/casts.h
@@ -116,8 +116,7 @@
 
 template<typename To, typename From>
 inline To bit_cast(const From& from) {
-  GOOGLE_COMPILE_ASSERT(sizeof(From) == sizeof(To),
-                        bit_cast_with_different_sizes);
+  static_assert(sizeof(From) == sizeof(To), "bit_cast_with_different_sizes");
   To dest;
   memcpy(&dest, &from, sizeof(dest));
   return dest;
diff --git a/src/google/protobuf/stubs/common.h b/src/google/protobuf/stubs/common.h
index 2dfcc9b..050497f 100644
--- a/src/google/protobuf/stubs/common.h
+++ b/src/google/protobuf/stubs/common.h
@@ -82,7 +82,7 @@
 
 // The current version, represented as a single integer to make comparison
 // easier:  major * 10^6 + minor * 10^3 + micro
-#define GOOGLE_PROTOBUF_VERSION 3015006
+#define GOOGLE_PROTOBUF_VERSION 3015008
 
 // A suffix string for alpha, beta or rc releases. Empty for stable releases.
 #define GOOGLE_PROTOBUF_VERSION_SUFFIX ""
@@ -123,7 +123,6 @@
 // ===================================================================
 // from google3/util/utf8/public/unilib.h
 
-class StringPiece;
 namespace internal {
 
 // Checks if the buffer contains structurally-valid UTF-8.  Implemented in
diff --git a/src/google/protobuf/stubs/logging.h b/src/google/protobuf/stubs/logging.h
index 110ccdc..8ecc2fa 100644
--- a/src/google/protobuf/stubs/logging.h
+++ b/src/google/protobuf/stubs/logging.h
@@ -34,6 +34,7 @@
 #include <google/protobuf/stubs/macros.h>
 #include <google/protobuf/stubs/port.h>
 #include <google/protobuf/stubs/status.h>
+#include <google/protobuf/stubs/stringpiece.h>
 
 #include <google/protobuf/port_def.inc>
 
@@ -64,7 +65,6 @@
 #endif
 };
 
-class StringPiece;
 class uint128;
 namespace internal {
 
diff --git a/src/google/protobuf/stubs/macros.h b/src/google/protobuf/stubs/macros.h
index c556d02..fcb0687 100644
--- a/src/google/protobuf/stubs/macros.h
+++ b/src/google/protobuf/stubs/macros.h
@@ -31,21 +31,19 @@
 #ifndef GOOGLE_PROTOBUF_MACROS_H__
 #define GOOGLE_PROTOBUF_MACROS_H__
 
-#include <google/protobuf/stubs/port.h>
-
 namespace google {
 namespace protobuf {
 
 #undef GOOGLE_DISALLOW_EVIL_CONSTRUCTORS
 #define GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(TypeName)    \
-  TypeName(const TypeName&);                           \
-  void operator=(const TypeName&)
+  TypeName(const TypeName&) = delete;                  \
+  void operator=(const TypeName&) = delete
 
 #undef GOOGLE_DISALLOW_IMPLICIT_CONSTRUCTORS
 #define GOOGLE_DISALLOW_IMPLICIT_CONSTRUCTORS(TypeName) \
-  TypeName();                                           \
-  TypeName(const TypeName&);                            \
-  void operator=(const TypeName&)
+  TypeName() = delete;                                  \
+  TypeName(const TypeName&) = delete;                   \
+  void operator=(const TypeName&) = delete
 
 // ===================================================================
 // from google3/base/basictypes.h
@@ -89,31 +87,6 @@
   ((sizeof(a) / sizeof(*(a))) / \
    static_cast<size_t>(!(sizeof(a) % sizeof(*(a)))))
 
-// The COMPILE_ASSERT macro can be used to verify that a compile time
-// expression is true. For example, you could use it to verify the
-// size of a static array:
-//
-//   COMPILE_ASSERT(ARRAYSIZE(content_type_names) == CONTENT_NUM_TYPES,
-//                  content_type_names_incorrect_size);
-//
-// or to make sure a struct is smaller than a certain size:
-//
-//   COMPILE_ASSERT(sizeof(foo) < 128, foo_too_large);
-//
-// The second argument to the macro is the name of the variable. If
-// the expression is false, most compilers will issue a warning/error
-// containing the name of the variable.
-
-namespace internal {
-
-template <bool>
-struct CompileAssert {
-};
-
-}  // namespace internal
-
-#define GOOGLE_COMPILE_ASSERT(expr, msg) static_assert(expr, #msg)
-
 }  // namespace protobuf
 }  // namespace google
 
diff --git a/src/google/protobuf/stubs/mutex.h b/src/google/protobuf/stubs/mutex.h
index 82b62a6..bff9681 100644
--- a/src/google/protobuf/stubs/mutex.h
+++ b/src/google/protobuf/stubs/mutex.h
@@ -116,7 +116,7 @@
 // mutexes.
 class GOOGLE_PROTOBUF_CAPABILITY("mutex") PROTOBUF_EXPORT WrappedMutex {
  public:
-  constexpr WrappedMutex() = default;
+  constexpr WrappedMutex() {}
   void Lock() GOOGLE_PROTOBUF_ACQUIRE() { mu_.lock(); }
   void Unlock() GOOGLE_PROTOBUF_RELEASE() { mu_.unlock(); }
   // Crash if this Mutex is not held exclusively by this thread.
diff --git a/src/google/protobuf/stubs/status_macros.h b/src/google/protobuf/stubs/status_macros.h
index 0c64317..407ff4c 100644
--- a/src/google/protobuf/stubs/status_macros.h
+++ b/src/google/protobuf/stubs/status_macros.h
@@ -60,7 +60,7 @@
 template<typename T>
 Status DoAssignOrReturn(T& lhs, StatusOr<T> result) {
   if (result.ok()) {
-    lhs = result.ValueOrDie();
+    lhs = result.value();
   }
   return result.status();
 }
diff --git a/src/google/protobuf/stubs/statusor.cc b/src/google/protobuf/stubs/statusor.cc
index c744b8d..9c0a178 100644
--- a/src/google/protobuf/stubs/statusor.cc
+++ b/src/google/protobuf/stubs/statusor.cc
@@ -35,14 +35,14 @@
 namespace google {
 namespace protobuf {
 namespace util {
-namespace internal {
+namespace statusor_internal {
 
 void StatusOrHelper::Crash(const Status& status) {
   GOOGLE_LOG(FATAL) << "Attempting to fetch value instead of handling error "
                     << status.ToString();
 }
 
-}  // namespace internal
+}  // namespace statusor_internal
 }  // namespace util
 }  // namespace protobuf
 }  // namespace google
diff --git a/src/google/protobuf/stubs/statusor.h b/src/google/protobuf/stubs/statusor.h
index dc265f0..a569502 100644
--- a/src/google/protobuf/stubs/statusor.h
+++ b/src/google/protobuf/stubs/statusor.h
@@ -42,7 +42,7 @@
 //
 //  StatusOr<float> result = DoBigCalculationThatCouldFail();
 //  if (result.ok()) {
-//    float answer = result.ValueOrDie();
+//    float answer = result.value();
 //    printf("Big calculation yielded: %f", answer);
 //  } else {
 //    LOG(ERROR) << result.status();
@@ -52,17 +52,7 @@
 //
 //  StatusOr<Foo*> result = FooFactory::MakeNewFoo(arg);
 //  if (result.ok()) {
-//    std::unique_ptr<Foo> foo(result.ValueOrDie());
-//    foo->DoSomethingCool();
-//  } else {
-//    LOG(ERROR) << result.status();
-//  }
-//
-// Example client usage for a StatusOr<std::unique_ptr<T>>:
-//
-//  StatusOr<std::unique_ptr<Foo>> result = FooFactory::MakeNewFoo(arg);
-//  if (result.ok()) {
-//    std::unique_ptr<Foo> foo = result.ConsumeValueOrDie();
+//    std::unique_ptr<Foo> foo(result.value());
 //    foo->DoSomethingCool();
 //  } else {
 //    LOG(ERROR) << result.status();
@@ -93,17 +83,21 @@
 namespace google {
 namespace protobuf {
 namespace util {
+namespace statusor_internal {
 
 template<typename T>
 class StatusOr {
   template<typename U> friend class StatusOr;
 
  public:
+  using value_type = T;
+
+  // Construct a new StatusOr with Status::UNKNOWN status.
   // Construct a new StatusOr with UnknownError() status.
-  StatusOr();
+  explicit StatusOr();
 
   // Construct a new StatusOr with the given non-ok status. After calling
-  // this constructor, calls to ValueOrDie() will CHECK-fail.
+  // this constructor, calls to value() will CHECK-fail.
   //
   // NOTE: Not explicit - we want to use StatusOr<T> as a return
   // value, so it is convenient and sensible to be able to do 'return
@@ -116,7 +110,7 @@
 
   // Construct a new StatusOr with the given value. If T is a plain pointer,
   // value must not be nullptr. After calling this constructor, calls to
-  // ValueOrDie() will succeed, and calls to status() will return OK.
+  // value() will succeed, and calls to status() will return OK.
   //
   // NOTE: Not explicit - we want to use StatusOr<T> as a return type
   // so it is convenient and sensible to be able to do 'return T()'
@@ -149,9 +143,6 @@
   bool ok() const;
 
   // Returns a reference to our current value, or CHECK-fails if !this->ok().
-  // If you need to initialize a T object from the stored value,
-  // ConsumeValueOrDie() may be more efficient.
-  const T& ValueOrDie() const;
   const T& value () const;
 
  private:
@@ -162,8 +153,6 @@
 ////////////////////////////////////////////////////////////////////////////////
 // Implementation details for StatusOr<T>
 
-namespace internal {
-
 class PROTOBUF_EXPORT StatusOrHelper {
  public:
   // Move type-agnostic error handling to the .cc.
@@ -185,8 +174,6 @@
   static inline bool IsValueNull(const T* t) { return t == nullptr; }
 };
 
-}  // namespace internal
-
 template <typename T>
 inline StatusOr<T>::StatusOr() : status_(util::UnknownError("")) {}
 
@@ -201,7 +188,7 @@
 
 template<typename T>
 inline StatusOr<T>::StatusOr(const T& value) {
-  if (internal::StatusOrHelper::Specialize<T>::IsValueNull(value)) {
+  if (StatusOrHelper::Specialize<T>::IsValueNull(value)) {
     status_ = util::InternalError("nullptr is not a valid argument.");
   } else {
     status_ = util::OkStatus();
@@ -246,20 +233,17 @@
 }
 
 template<typename T>
-inline const T& StatusOr<T>::ValueOrDie() const {
+inline const T& StatusOr<T>::value() const {
   if (!status_.ok()) {
-    internal::StatusOrHelper::Crash(status_);
+    StatusOrHelper::Crash(status_);
   }
   return value_;
 }
 
-template<typename T>
-inline const T& StatusOr<T>::value() const {
-  if (!status_.ok()) {
-    internal::StatusOrHelper::Crash(status_);
-  }
-  return value_;
-}
+}  // namespace statusor_internal
+
+using ::google::protobuf::util::statusor_internal::StatusOr;
+
 }  // namespace util
 }  // namespace protobuf
 }  // namespace google
diff --git a/src/google/protobuf/stubs/statusor_test.cc b/src/google/protobuf/stubs/statusor_test.cc
index c51945f..403adcc 100644
--- a/src/google/protobuf/stubs/statusor_test.cc
+++ b/src/google/protobuf/stubs/statusor_test.cc
@@ -84,7 +84,7 @@
   const int kI = 4;
   StatusOr<int> thing(kI);
   EXPECT_TRUE(thing.ok());
-  EXPECT_EQ(kI, thing.ValueOrDie());
+  EXPECT_EQ(kI, thing.value());
 }
 
 TEST(StatusOr, TestCopyCtorStatusOk) {
@@ -92,7 +92,7 @@
   StatusOr<int> original(kI);
   StatusOr<int> copy(original);
   EXPECT_EQ(original.status(), copy.status());
-  EXPECT_EQ(original.ValueOrDie(), copy.ValueOrDie());
+  EXPECT_EQ(original.value(), copy.value());
 }
 
 TEST(StatusOr, TestCopyCtorStatusNotOk) {
@@ -106,7 +106,7 @@
   StatusOr<int>    original(kI);
   StatusOr<double> copy(original);
   EXPECT_EQ(original.status(), copy.status());
-  EXPECT_EQ(original.ValueOrDie(), copy.ValueOrDie());
+  EXPECT_EQ(original.value(), copy.value());
 }
 
 TEST(StatusOr, TestCopyCtorStatusNotOkConverting) {
@@ -121,7 +121,7 @@
   StatusOr<int> target;
   target = source;
   EXPECT_EQ(source.status(), target.status());
-  EXPECT_EQ(source.ValueOrDie(), target.ValueOrDie());
+  EXPECT_EQ(source.value(), target.value());
 }
 
 TEST(StatusOr, TestAssignmentStatusNotOk) {
@@ -137,7 +137,7 @@
   StatusOr<double> target;
   target = source;
   EXPECT_EQ(source.status(), target.status());
-  EXPECT_DOUBLE_EQ(source.ValueOrDie(), target.ValueOrDie());
+  EXPECT_DOUBLE_EQ(source.value(), target.value());
 }
 
 TEST(StatusOr, TestAssignmentStatusNotOkConverting) {
@@ -158,13 +158,13 @@
 TEST(StatusOr, TestValue) {
   const int kI = 4;
   StatusOr<int> thing(kI);
-  EXPECT_EQ(kI, thing.ValueOrDie());
+  EXPECT_EQ(kI, thing.value());
 }
 
 TEST(StatusOr, TestValueConst) {
   const int kI = 4;
   const StatusOr<int> thing(kI);
-  EXPECT_EQ(kI, thing.ValueOrDie());
+  EXPECT_EQ(kI, thing.value());
 }
 
 TEST(StatusOr, TestPointerDefaultCtor) {
@@ -183,7 +183,7 @@
   const int kI = 4;
   StatusOr<const int*> thing(&kI);
   EXPECT_TRUE(thing.ok());
-  EXPECT_EQ(&kI, thing.ValueOrDie());
+  EXPECT_EQ(&kI, thing.value());
 }
 
 TEST(StatusOr, TestPointerCopyCtorStatusOk) {
@@ -191,7 +191,7 @@
   StatusOr<const int*> original(&kI);
   StatusOr<const int*> copy(original);
   EXPECT_EQ(original.status(), copy.status());
-  EXPECT_EQ(original.ValueOrDie(), copy.ValueOrDie());
+  EXPECT_EQ(original.value(), copy.value());
 }
 
 TEST(StatusOr, TestPointerCopyCtorStatusNotOk) {
@@ -205,8 +205,7 @@
   StatusOr<Derived*> original(&derived);
   StatusOr<Base2*>   copy(original);
   EXPECT_EQ(original.status(), copy.status());
-  EXPECT_EQ(static_cast<const Base2*>(original.ValueOrDie()),
-            copy.ValueOrDie());
+  EXPECT_EQ(static_cast<const Base2*>(original.value()), copy.value());
 }
 
 TEST(StatusOr, TestPointerCopyCtorStatusNotOkConverting) {
@@ -221,7 +220,7 @@
   StatusOr<const int*> target;
   target = source;
   EXPECT_EQ(source.status(), target.status());
-  EXPECT_EQ(source.ValueOrDie(), target.ValueOrDie());
+  EXPECT_EQ(source.value(), target.value());
 }
 
 TEST(StatusOr, TestPointerAssignmentStatusNotOk) {
@@ -237,8 +236,7 @@
   StatusOr<Base2*>   target;
   target = source;
   EXPECT_EQ(source.status(), target.status());
-  EXPECT_EQ(static_cast<const Base2*>(source.ValueOrDie()),
-            target.ValueOrDie());
+  EXPECT_EQ(static_cast<const Base2*>(source.value()), target.value());
 }
 
 TEST(StatusOr, TestPointerAssignmentStatusNotOkConverting) {
@@ -259,13 +257,13 @@
 TEST(StatusOr, TestPointerValue) {
   const int kI = 0;
   StatusOr<const int*> thing(&kI);
-  EXPECT_EQ(&kI, thing.ValueOrDie());
+  EXPECT_EQ(&kI, thing.value());
 }
 
 TEST(StatusOr, TestPointerValueConst) {
   const int kI = 0;
   const StatusOr<const int*> thing(&kI);
-  EXPECT_EQ(&kI, thing.ValueOrDie());
+  EXPECT_EQ(&kI, thing.value());
 }
 
 }  // namespace
diff --git a/src/google/protobuf/stubs/stringpiece.cc b/src/google/protobuf/stubs/stringpiece.cc
index 353c78c..a014d1f 100644
--- a/src/google/protobuf/stubs/stringpiece.cc
+++ b/src/google/protobuf/stubs/stringpiece.cc
@@ -39,31 +39,13 @@
 
 namespace google {
 namespace protobuf {
+namespace stringpiece_internal {
+
 std::ostream& operator<<(std::ostream& o, StringPiece piece) {
   o.write(piece.data(), piece.size());
   return o;
 }
 
-// Out-of-line error path.
-void StringPiece::LogFatalSizeTooBig(size_t size, const char* details) {
-  GOOGLE_LOG(FATAL) << "size too big: " << size << " details: " << details;
-}
-
-StringPiece::StringPiece(StringPiece x, stringpiece_ssize_type pos)
-    : ptr_(x.ptr_ + pos), length_(x.length_ - pos) {
-  GOOGLE_DCHECK_LE(0, pos);
-  GOOGLE_DCHECK_LE(pos, x.length_);
-}
-
-StringPiece::StringPiece(StringPiece x,
-                         stringpiece_ssize_type pos,
-                         stringpiece_ssize_type len)
-    : ptr_(x.ptr_ + pos), length_(std::min(len, x.length_ - pos)) {
-  GOOGLE_DCHECK_LE(0, pos);
-  GOOGLE_DCHECK_LE(pos, x.length_);
-  GOOGLE_DCHECK_GE(len, 0);
-}
-
 void StringPiece::CopyToString(std::string* target) const {
   target->assign(ptr_, length_);
 }
@@ -89,10 +71,9 @@
   return false;
 }
 
-stringpiece_ssize_type StringPiece::copy(char* buf,
-                                         size_type n,
-                                         size_type pos) const {
-  stringpiece_ssize_type ret = std::min(length_ - pos, n);
+StringPiece::size_type StringPiece::copy(
+    char* buf, size_type n, size_type pos) const {
+  size_type ret = std::min(length_ - pos, n);
   memcpy(buf, ptr_ + pos, ret);
   return ret;
 }
@@ -101,7 +82,8 @@
   return find(s, 0) != npos;
 }
 
-stringpiece_ssize_type StringPiece::find(StringPiece s, size_type pos) const {
+StringPiece::size_type StringPiece::find(
+    StringPiece s, size_type pos) const {
   if (length_ <= 0 || pos > static_cast<size_type>(length_)) {
     if (length_ == 0 && pos == 0 && s.length_ == 0) return 0;
     return npos;
@@ -111,7 +93,7 @@
   return result == ptr_ + length_ ? npos : result - ptr_;
 }
 
-stringpiece_ssize_type StringPiece::find(char c, size_type pos) const {
+StringPiece::size_type StringPiece::find(char c, size_type pos) const {
   if (length_ <= 0 || pos >= static_cast<size_type>(length_)) {
     return npos;
   }
@@ -120,7 +102,7 @@
   return result != nullptr ? result - ptr_ : npos;
 }
 
-stringpiece_ssize_type StringPiece::rfind(StringPiece s, size_type pos) const {
+StringPiece::size_type StringPiece::rfind(StringPiece s, size_type pos) const {
   if (length_ < s.length_) return npos;
   const size_t ulen = length_;
   if (s.length_ == 0) return std::min(ulen, pos);
@@ -131,10 +113,10 @@
 }
 
 // Search range is [0..pos] inclusive.  If pos == npos, search everything.
-stringpiece_ssize_type StringPiece::rfind(char c, size_type pos) const {
+StringPiece::size_type StringPiece::rfind(char c, size_type pos) const {
   // Note: memrchr() is not available on Windows.
-  if (length_ <= 0) return npos;
-  for (stringpiece_ssize_type i =
+  if (empty()) return npos;
+  for (difference_type i =
       std::min(pos, static_cast<size_type>(length_ - 1));
        i >= 0; --i) {
     if (ptr_[i] == c) {
@@ -154,16 +136,16 @@
 //   bool table[UCHAR_MAX + 1]
 static inline void BuildLookupTable(StringPiece characters_wanted,
                                     bool* table) {
-  const stringpiece_ssize_type length = characters_wanted.length();
+  const StringPiece::size_type length = characters_wanted.length();
   const char* const data = characters_wanted.data();
-  for (stringpiece_ssize_type i = 0; i < length; ++i) {
+  for (StringPiece::size_type i = 0; i < length; ++i) {
     table[static_cast<unsigned char>(data[i])] = true;
   }
 }
 
-stringpiece_ssize_type StringPiece::find_first_of(StringPiece s,
-                                                  size_type pos) const {
-  if (length_ <= 0 || s.length_ <= 0) {
+StringPiece::size_type StringPiece::find_first_of(
+    StringPiece s, size_type pos) const {
+  if (empty() || s.empty()) {
     return npos;
   }
   // Avoid the cost of BuildLookupTable() for a single-character search.
@@ -171,7 +153,7 @@
 
   bool lookup[UCHAR_MAX + 1] = { false };
   BuildLookupTable(s, lookup);
-  for (stringpiece_ssize_type i = pos; i < length_; ++i) {
+  for (size_type i = pos; i < length_; ++i) {
     if (lookup[static_cast<unsigned char>(ptr_[i])]) {
       return i;
     }
@@ -179,16 +161,16 @@
   return npos;
 }
 
-stringpiece_ssize_type StringPiece::find_first_not_of(StringPiece s,
-                                                      size_type pos) const {
-  if (length_ <= 0) return npos;
-  if (s.length_ <= 0) return 0;
+StringPiece::size_type StringPiece::find_first_not_of(
+    StringPiece s, size_type pos) const {
+  if (empty()) return npos;
+  if (s.empty()) return 0;
   // Avoid the cost of BuildLookupTable() for a single-character search.
   if (s.length_ == 1) return find_first_not_of(s.ptr_[0], pos);
 
   bool lookup[UCHAR_MAX + 1] = { false };
   BuildLookupTable(s, lookup);
-  for (stringpiece_ssize_type i = pos; i < length_; ++i) {
+  for (size_type i = pos; i < length_; ++i) {
     if (!lookup[static_cast<unsigned char>(ptr_[i])]) {
       return i;
     }
@@ -196,9 +178,9 @@
   return npos;
 }
 
-stringpiece_ssize_type StringPiece::find_first_not_of(char c,
-                                                      size_type pos) const {
-  if (length_ <= 0) return npos;
+StringPiece::size_type StringPiece::find_first_not_of(
+    char c, size_type pos) const {
+  if (empty()) return npos;
 
   for (; pos < static_cast<size_type>(length_); ++pos) {
     if (ptr_[pos] != c) {
@@ -208,15 +190,15 @@
   return npos;
 }
 
-stringpiece_ssize_type StringPiece::find_last_of(StringPiece s,
-                                                 size_type pos) const {
-  if (length_ <= 0 || s.length_ <= 0) return npos;
+StringPiece::size_type StringPiece::find_last_of(
+    StringPiece s, size_type pos) const {
+  if (empty() || s.empty()) return npos;
   // Avoid the cost of BuildLookupTable() for a single-character search.
   if (s.length_ == 1) return find_last_of(s.ptr_[0], pos);
 
   bool lookup[UCHAR_MAX + 1] = { false };
   BuildLookupTable(s, lookup);
-  for (stringpiece_ssize_type i =
+  for (difference_type i =
        std::min(pos, static_cast<size_type>(length_ - 1)); i >= 0; --i) {
     if (lookup[static_cast<unsigned char>(ptr_[i])]) {
       return i;
@@ -225,12 +207,12 @@
   return npos;
 }
 
-stringpiece_ssize_type StringPiece::find_last_not_of(StringPiece s,
-                                                     size_type pos) const {
-  if (length_ <= 0) return npos;
+StringPiece::size_type StringPiece::find_last_not_of(
+    StringPiece s, size_type pos) const {
+  if (empty()) return npos;
 
-  stringpiece_ssize_type i = std::min(pos, static_cast<size_type>(length_ - 1));
-  if (s.length_ <= 0) return i;
+  size_type i = std::min(pos, length()-1);
+  if (s.empty()) return i;
 
   // Avoid the cost of BuildLookupTable() for a single-character search.
   if (s.length_ == 1) return find_last_not_of(s.ptr_[0], pos);
@@ -245,11 +227,11 @@
   return npos;
 }
 
-stringpiece_ssize_type StringPiece::find_last_not_of(char c,
-                                                     size_type pos) const {
-  if (length_ <= 0) return npos;
+StringPiece::size_type StringPiece::find_last_not_of(
+    char c, size_type pos) const {
+  if (empty()) return npos;
 
-  for (stringpiece_ssize_type i =
+  for (difference_type i =
        std::min(pos, static_cast<size_type>(length_ - 1)); i >= 0; --i) {
     if (ptr_[i] != c) {
       return i;
@@ -259,12 +241,13 @@
 }
 
 StringPiece StringPiece::substr(size_type pos, size_type n) const {
-  if (pos > length_) pos = length_;
-  if (n > length_ - pos) n = length_ - pos;
+  if (pos > length()) pos = length();
+  if (n > length_ - pos) n = length() - pos;
   return StringPiece(ptr_ + pos, n);
 }
 
 const StringPiece::size_type StringPiece::npos = size_type(-1);
 
+}  // namespace stringpiece_internal
 }  // namespace protobuf
 }  // namespace google
diff --git a/src/google/protobuf/stubs/stringpiece.h b/src/google/protobuf/stubs/stringpiece.h
index 0a426fe..1e896e0 100644
--- a/src/google/protobuf/stubs/stringpiece.h
+++ b/src/google/protobuf/stubs/stringpiece.h
@@ -154,52 +154,26 @@
 
 namespace google {
 namespace protobuf {
-// StringPiece has *two* size types.
-// StringPiece::size_type
-//   is unsigned
-//   is 32 bits in LP32, 64 bits in LP64, 64 bits in LLP64
-//   no future changes intended
-// stringpiece_ssize_type
-//   is signed
-//   is 32 bits in LP32, 64 bits in LP64, 64 bits in LLP64
-//   future changes intended: http://go/64BitStringPiece
-//
-typedef std::string::difference_type stringpiece_ssize_type;
-
-// STRINGPIECE_CHECK_SIZE protects us from 32-bit overflows.
-// TODO(mec): delete this after stringpiece_ssize_type goes 64 bit.
-#if !defined(NDEBUG)
-#define STRINGPIECE_CHECK_SIZE 1
-#elif defined(_FORTIFY_SOURCE) && _FORTIFY_SOURCE > 0
-#define STRINGPIECE_CHECK_SIZE 1
-#else
-#define STRINGPIECE_CHECK_SIZE 0
-#endif
+namespace stringpiece_internal {
 
 class PROTOBUF_EXPORT StringPiece {
+ public:
+  using traits_type = std::char_traits<char>;
+  using value_type = char;
+  using pointer = char*;
+  using const_pointer = const char*;
+  using reference = char&;
+  using const_reference = const char&;
+  using const_iterator = const char*;
+  using iterator = const_iterator;
+  using const_reverse_iterator = std::reverse_iterator<const_iterator>;
+  using reverse_iterator = const_reverse_iterator;
+  using size_type = size_t;
+  using difference_type = std::ptrdiff_t;
+
  private:
   const char* ptr_;
-  stringpiece_ssize_type length_;
-
-  // Prevent overflow in debug mode or fortified mode.
-  // sizeof(stringpiece_ssize_type) may be smaller than sizeof(size_t).
-  static stringpiece_ssize_type CheckedSsizeTFromSizeT(size_t size) {
-#if STRINGPIECE_CHECK_SIZE > 0
-#ifdef max
-#undef max
-#endif
-    if (size > static_cast<size_t>(
-        std::numeric_limits<stringpiece_ssize_type>::max())) {
-      // Some people grep for this message in logs
-      // so take care if you ever change it.
-      LogFatalSizeTooBig(size, "size_t to int conversion");
-    }
-#endif
-    return static_cast<stringpiece_ssize_type>(size);
-  }
-
-  // Out-of-line error path.
-  static void LogFatalSizeTooBig(size_t size, const char* details);
+  size_type length_;
 
  public:
   // We provide non-explicit singleton constructors so users can pass
@@ -213,7 +187,7 @@
   StringPiece(const char* str)  // NOLINT(runtime/explicit)
       : ptr_(str), length_(0) {
     if (str != nullptr) {
-      length_ = CheckedSsizeTFromSizeT(strlen(str));
+      length_ = strlen(str);
     }
   }
 
@@ -221,78 +195,40 @@
   StringPiece(  // NOLINT(runtime/explicit)
       const std::basic_string<char, std::char_traits<char>, Allocator>& str)
       : ptr_(str.data()), length_(0) {
-    length_ = CheckedSsizeTFromSizeT(str.size());
+    length_ = str.size();
   }
 
-  StringPiece(const char* offset, stringpiece_ssize_type len)
-      : ptr_(offset), length_(len) {
-    assert(len >= 0);
-  }
-
-  // Substring of another StringPiece.
-  // pos must be non-negative and <= x.length().
-  StringPiece(StringPiece x, stringpiece_ssize_type pos);
-  // Substring of another StringPiece.
-  // pos must be non-negative and <= x.length().
-  // len must be non-negative and will be pinned to at most x.length() - pos.
-  StringPiece(StringPiece x,
-              stringpiece_ssize_type pos,
-              stringpiece_ssize_type len);
+  StringPiece(const char* offset, size_type len)
+      : ptr_(offset), length_(len) {}
 
   // data() may return a pointer to a buffer with embedded NULs, and the
   // returned buffer may or may not be null terminated.  Therefore it is
   // typically a mistake to pass data() to a routine that expects a NUL
   // terminated string.
-  const char* data() const { return ptr_; }
-  stringpiece_ssize_type size() const { return length_; }
-  stringpiece_ssize_type length() const { return length_; }
+  const_pointer data() const { return ptr_; }
+  size_type size() const { return length_; }
+  size_type length() const { return length_; }
   bool empty() const { return length_ == 0; }
 
-  void clear() {
-    ptr_ = nullptr;
-    length_ = 0;
-  }
-
-  void set(const char* data, stringpiece_ssize_type len) {
-    assert(len >= 0);
-    ptr_ = data;
-    length_ = len;
-  }
-
-  void set(const char* str) {
-    ptr_ = str;
-    if (str != nullptr)
-      length_ = CheckedSsizeTFromSizeT(strlen(str));
-    else
-      length_ = 0;
-  }
-
-  void set(const void* data, stringpiece_ssize_type len) {
-    ptr_ = reinterpret_cast<const char*>(data);
-    length_ = len;
-  }
-
-  char operator[](stringpiece_ssize_type i) const {
-    assert(0 <= i);
+  char operator[](size_type i) const {
     assert(i < length_);
     return ptr_[i];
   }
 
-  void remove_prefix(stringpiece_ssize_type n) {
+  void remove_prefix(size_type n) {
     assert(length_ >= n);
     ptr_ += n;
     length_ -= n;
   }
 
-  void remove_suffix(stringpiece_ssize_type n) {
+  void remove_suffix(size_type n) {
     assert(length_ >= n);
     length_ -= n;
   }
 
   // returns {-1, 0, 1}
   int compare(StringPiece x) const {
-    const stringpiece_ssize_type min_size =
-        length_ < x.length_ ? length_ : x.length_;
+    size_type min_size = length_ < x.length_ ? length_ : x.length_;
     int r = memcmp(ptr_, x.ptr_, static_cast<size_t>(min_size));
     if (r < 0) return -1;
     if (r > 0) return 1;
@@ -336,53 +272,41 @@
   bool ConsumeFromEnd(StringPiece x);
 
   // standard STL container boilerplate
-  typedef char value_type;
-  typedef const char* pointer;
-  typedef const char& reference;
-  typedef const char& const_reference;
-  typedef size_t size_type;
-  typedef ptrdiff_t difference_type;
   static const size_type npos;
-  typedef const char* const_iterator;
-  typedef const char* iterator;
-  typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
-  typedef std::reverse_iterator<iterator> reverse_iterator;
-  iterator begin() const { return ptr_; }
-  iterator end() const { return ptr_ + length_; }
+  const_iterator begin() const { return ptr_; }
+  const_iterator end() const { return ptr_ + length_; }
   const_reverse_iterator rbegin() const {
     return const_reverse_iterator(ptr_ + length_);
   }
   const_reverse_iterator rend() const {
     return const_reverse_iterator(ptr_);
   }
-  stringpiece_ssize_type max_size() const { return length_; }
-  stringpiece_ssize_type capacity() const { return length_; }
+  size_type max_size() const { return length_; }
+  size_type capacity() const { return length_; }
 
   // cpplint.py emits a false positive [build/include_what_you_use]
-  stringpiece_ssize_type copy(char* buf, size_type n, size_type pos = 0) const;  // NOLINT
+  size_type copy(char* buf, size_type n, size_type pos = 0) const;  // NOLINT
 
   bool contains(StringPiece s) const;
 
-  stringpiece_ssize_type find(StringPiece s, size_type pos = 0) const;
-  stringpiece_ssize_type find(char c, size_type pos = 0) const;
-  stringpiece_ssize_type rfind(StringPiece s, size_type pos = npos) const;
-  stringpiece_ssize_type rfind(char c, size_type pos = npos) const;
+  size_type find(StringPiece s, size_type pos = 0) const;
+  size_type find(char c, size_type pos = 0) const;
+  size_type rfind(StringPiece s, size_type pos = npos) const;
+  size_type rfind(char c, size_type pos = npos) const;
 
-  stringpiece_ssize_type find_first_of(StringPiece s, size_type pos = 0) const;
-  stringpiece_ssize_type find_first_of(char c, size_type pos = 0) const {
+  size_type find_first_of(StringPiece s, size_type pos = 0) const;
+  size_type find_first_of(char c, size_type pos = 0) const {
     return find(c, pos);
   }
-  stringpiece_ssize_type find_first_not_of(StringPiece s,
-                                           size_type pos = 0) const;
-  stringpiece_ssize_type find_first_not_of(char c, size_type pos = 0) const;
-  stringpiece_ssize_type find_last_of(StringPiece s,
-                                      size_type pos = npos) const;
-  stringpiece_ssize_type find_last_of(char c, size_type pos = npos) const {
+  size_type find_first_not_of(StringPiece s, size_type pos = 0) const;
+  size_type find_first_not_of(char c, size_type pos = 0) const;
+  size_type find_last_of(StringPiece s, size_type pos = npos) const;
+  size_type find_last_of(char c, size_type pos = npos) const {
     return rfind(c, pos);
   }
-  stringpiece_ssize_type find_last_not_of(StringPiece s,
+  size_type find_last_not_of(StringPiece s,
                                           size_type pos = npos) const;
-  stringpiece_ssize_type find_last_not_of(char c, size_type pos = npos) const;
+  size_type find_last_not_of(char c, size_type pos = npos) const;
 
   StringPiece substr(size_type pos, size_type n = npos) const;
 };
@@ -391,7 +315,7 @@
 // one of the arguments is a literal, the compiler can elide a lot of the
 // following comparisons.
 inline bool operator==(StringPiece x, StringPiece y) {
-  stringpiece_ssize_type len = x.size();
+  StringPiece::size_type len = x.size();
   if (len != y.size()) {
     return false;
   }
@@ -405,7 +329,7 @@
 }
 
 inline bool operator<(StringPiece x, StringPiece y) {
-  const stringpiece_ssize_type min_size =
+  const StringPiece::size_type min_size =
       x.size() < y.size() ? x.size() : y.size();
   const int r = memcmp(x.data(), y.data(), static_cast<size_t>(min_size));
   return (r < 0) || (r == 0 && x.size() < y.size());
@@ -426,6 +350,10 @@
 // allow StringPiece to be logged
 extern std::ostream& operator<<(std::ostream& o, StringPiece piece);
 
+}  // namespace stringpiece_internal
+
+using ::google::protobuf::stringpiece_internal::StringPiece;
+
 }  // namespace protobuf
 }  // namespace google
 
diff --git a/src/google/protobuf/stubs/stringpiece_unittest.cc b/src/google/protobuf/stubs/stringpiece_unittest.cc
index 846e1ae..e85a2e5 100644
--- a/src/google/protobuf/stubs/stringpiece_unittest.cc
+++ b/src/google/protobuf/stubs/stringpiece_unittest.cc
@@ -305,16 +305,9 @@
   const StringPiece a("abcdefghijklmnopqrstuvwxyz");
   const StringPiece b("abc");
   const StringPiece c("xyz");
-  StringPiece d("foobar");
   const StringPiece e;
   const StringPiece f("123" "\0" "456", 7);
 
-  d.clear();
-  EXPECT_EQ(d.size(), 0);
-  EXPECT_TRUE(d.empty());
-  EXPECT_TRUE(d.data() == nullptr);
-  EXPECT_TRUE(d.begin() == d.end());
-
   EXPECT_EQ(StringPiece::npos, std::string::npos);
 
   EXPECT_EQ(a.find(b), 0);
@@ -324,26 +317,16 @@
   EXPECT_EQ(a.find(c, StringPiece::npos), StringPiece::npos);
   EXPECT_EQ(b.find(c), StringPiece::npos);
   EXPECT_EQ(b.find(c, StringPiece::npos), StringPiece::npos);
-  EXPECT_EQ(a.find(d), 0);
   EXPECT_EQ(a.find(e), 0);
-  EXPECT_EQ(a.find(d, 12), 12);
   EXPECT_EQ(a.find(e, 17), 17);
   StringPiece g("xx not found bb");
   EXPECT_EQ(a.find(g), StringPiece::npos);
   // empty string nonsense
-  EXPECT_EQ(d.find(b), StringPiece::npos);
   EXPECT_EQ(e.find(b), StringPiece::npos);
-  EXPECT_EQ(d.find(b, 4), StringPiece::npos);
   EXPECT_EQ(e.find(b, 7), StringPiece::npos);
 
   size_t empty_search_pos = std::string().find(std::string());
-  EXPECT_EQ(d.find(d), empty_search_pos);
-  EXPECT_EQ(d.find(e), empty_search_pos);
-  EXPECT_EQ(e.find(d), empty_search_pos);
   EXPECT_EQ(e.find(e), empty_search_pos);
-  EXPECT_EQ(d.find(d, 4), std::string().find(std::string(), 4));
-  EXPECT_EQ(d.find(e, 4), std::string().find(std::string(), 4));
-  EXPECT_EQ(e.find(d, 4), std::string().find(std::string(), 4));
   EXPECT_EQ(e.find(e, 4), std::string().find(std::string(), 4));
 
   EXPECT_EQ(a.find('a'), 0);
@@ -359,13 +342,9 @@
   EXPECT_EQ(g.find('o', 5), 8);
   EXPECT_EQ(a.find('b', 5), StringPiece::npos);
   // empty string nonsense
-  EXPECT_EQ(d.find('\0'), StringPiece::npos);
   EXPECT_EQ(e.find('\0'), StringPiece::npos);
-  EXPECT_EQ(d.find('\0', 4), StringPiece::npos);
   EXPECT_EQ(e.find('\0', 7), StringPiece::npos);
-  EXPECT_EQ(d.find('x'), StringPiece::npos);
   EXPECT_EQ(e.find('x'), StringPiece::npos);
-  EXPECT_EQ(d.find('x', 4), StringPiece::npos);
   EXPECT_EQ(e.find('x', 7), StringPiece::npos);
 
   EXPECT_EQ(a.rfind(b), 0);
@@ -376,23 +355,13 @@
   EXPECT_EQ(a.rfind(c, 0), StringPiece::npos);
   EXPECT_EQ(b.rfind(c), StringPiece::npos);
   EXPECT_EQ(b.rfind(c, 0), StringPiece::npos);
-  EXPECT_EQ(a.rfind(d), a.as_string().rfind(std::string()));
   EXPECT_EQ(a.rfind(e), a.as_string().rfind(std::string()));
-  EXPECT_EQ(a.rfind(d, 12), 12);
   EXPECT_EQ(a.rfind(e, 17), 17);
   EXPECT_EQ(a.rfind(g), StringPiece::npos);
-  EXPECT_EQ(d.rfind(b), StringPiece::npos);
   EXPECT_EQ(e.rfind(b), StringPiece::npos);
-  EXPECT_EQ(d.rfind(b, 4), StringPiece::npos);
   EXPECT_EQ(e.rfind(b, 7), StringPiece::npos);
   // empty string nonsense
-  EXPECT_EQ(d.rfind(d, 4), std::string().rfind(std::string()));
-  EXPECT_EQ(e.rfind(d, 7), std::string().rfind(std::string()));
-  EXPECT_EQ(d.rfind(e, 4), std::string().rfind(std::string()));
   EXPECT_EQ(e.rfind(e, 7), std::string().rfind(std::string()));
-  EXPECT_EQ(d.rfind(d), std::string().rfind(std::string()));
-  EXPECT_EQ(e.rfind(d), std::string().rfind(std::string()));
-  EXPECT_EQ(d.rfind(e), std::string().rfind(std::string()));
   EXPECT_EQ(e.rfind(e), std::string().rfind(std::string()));
 
   EXPECT_EQ(g.rfind('o'), 8);
@@ -405,9 +374,7 @@
   EXPECT_EQ(f.rfind('3'), 2);
   EXPECT_EQ(f.rfind('5'), 5);
   // empty string nonsense
-  EXPECT_EQ(d.rfind('o'), StringPiece::npos);
   EXPECT_EQ(e.rfind('o'), StringPiece::npos);
-  EXPECT_EQ(d.rfind('o', 4), StringPiece::npos);
   EXPECT_EQ(e.rfind('o', 7), StringPiece::npos);
 
   EXPECT_EQ(a.find_first_of(b), 0);
@@ -425,13 +392,8 @@
   EXPECT_EQ(a.find_first_of(f), StringPiece::npos);
   EXPECT_EQ(f.find_first_of(a), StringPiece::npos);
   // empty string nonsense
-  EXPECT_EQ(a.find_first_of(d), StringPiece::npos);
   EXPECT_EQ(a.find_first_of(e), StringPiece::npos);
-  EXPECT_EQ(d.find_first_of(b), StringPiece::npos);
   EXPECT_EQ(e.find_first_of(b), StringPiece::npos);
-  EXPECT_EQ(d.find_first_of(d), StringPiece::npos);
-  EXPECT_EQ(e.find_first_of(d), StringPiece::npos);
-  EXPECT_EQ(d.find_first_of(e), StringPiece::npos);
   EXPECT_EQ(e.find_first_of(e), StringPiece::npos);
 
   EXPECT_EQ(a.find_first_not_of(b), 3);
@@ -440,14 +402,9 @@
   EXPECT_EQ(c.find_first_not_of(a), StringPiece::npos);
   EXPECT_EQ(f.find_first_not_of(a), 0);
   EXPECT_EQ(a.find_first_not_of(f), 0);
-  EXPECT_EQ(a.find_first_not_of(d), 0);
   EXPECT_EQ(a.find_first_not_of(e), 0);
   // empty string nonsense
-  EXPECT_EQ(d.find_first_not_of(a), StringPiece::npos);
   EXPECT_EQ(e.find_first_not_of(a), StringPiece::npos);
-  EXPECT_EQ(d.find_first_not_of(d), StringPiece::npos);
-  EXPECT_EQ(e.find_first_not_of(d), StringPiece::npos);
-  EXPECT_EQ(d.find_first_not_of(e), StringPiece::npos);
   EXPECT_EQ(e.find_first_not_of(e), StringPiece::npos);
 
   StringPiece h("====");
@@ -459,9 +416,7 @@
   EXPECT_EQ(f.find_first_not_of('\0', 3), 4);
   EXPECT_EQ(f.find_first_not_of('\0', 2), 2);
   // empty string nonsense
-  EXPECT_EQ(d.find_first_not_of('x'), StringPiece::npos);
   EXPECT_EQ(e.find_first_not_of('x'), StringPiece::npos);
-  EXPECT_EQ(d.find_first_not_of('\0'), StringPiece::npos);
   EXPECT_EQ(e.find_first_not_of('\0'), StringPiece::npos);
 
   //  StringPiece g("xx not found bb");
@@ -483,21 +438,11 @@
   EXPECT_EQ(f.find_last_of(i, 6), 6);
   EXPECT_EQ(f.find_last_of(a, 4), StringPiece::npos);
   // empty string nonsense
-  EXPECT_EQ(f.find_last_of(d), StringPiece::npos);
   EXPECT_EQ(f.find_last_of(e), StringPiece::npos);
-  EXPECT_EQ(f.find_last_of(d, 4), StringPiece::npos);
   EXPECT_EQ(f.find_last_of(e, 4), StringPiece::npos);
-  EXPECT_EQ(d.find_last_of(d), StringPiece::npos);
-  EXPECT_EQ(d.find_last_of(e), StringPiece::npos);
-  EXPECT_EQ(e.find_last_of(d), StringPiece::npos);
   EXPECT_EQ(e.find_last_of(e), StringPiece::npos);
-  EXPECT_EQ(d.find_last_of(f), StringPiece::npos);
   EXPECT_EQ(e.find_last_of(f), StringPiece::npos);
-  EXPECT_EQ(d.find_last_of(d, 4), StringPiece::npos);
-  EXPECT_EQ(d.find_last_of(e, 4), StringPiece::npos);
-  EXPECT_EQ(e.find_last_of(d, 4), StringPiece::npos);
   EXPECT_EQ(e.find_last_of(e, 4), StringPiece::npos);
-  EXPECT_EQ(d.find_last_of(f, 4), StringPiece::npos);
   EXPECT_EQ(e.find_last_of(f, 4), StringPiece::npos);
 
   EXPECT_EQ(a.find_last_not_of(b), a.size()-1);
@@ -509,21 +454,11 @@
   EXPECT_EQ(a.find_last_not_of(b, 3), 3);
   EXPECT_EQ(a.find_last_not_of(b, 2), StringPiece::npos);
   // empty string nonsense
-  EXPECT_EQ(f.find_last_not_of(d), f.size()-1);
   EXPECT_EQ(f.find_last_not_of(e), f.size()-1);
-  EXPECT_EQ(f.find_last_not_of(d, 4), 4);
   EXPECT_EQ(f.find_last_not_of(e, 4), 4);
-  EXPECT_EQ(d.find_last_not_of(d), StringPiece::npos);
-  EXPECT_EQ(d.find_last_not_of(e), StringPiece::npos);
-  EXPECT_EQ(e.find_last_not_of(d), StringPiece::npos);
   EXPECT_EQ(e.find_last_not_of(e), StringPiece::npos);
-  EXPECT_EQ(d.find_last_not_of(f), StringPiece::npos);
   EXPECT_EQ(e.find_last_not_of(f), StringPiece::npos);
-  EXPECT_EQ(d.find_last_not_of(d, 4), StringPiece::npos);
-  EXPECT_EQ(d.find_last_not_of(e, 4), StringPiece::npos);
-  EXPECT_EQ(e.find_last_not_of(d, 4), StringPiece::npos);
   EXPECT_EQ(e.find_last_not_of(e, 4), StringPiece::npos);
-  EXPECT_EQ(d.find_last_not_of(f, 4), StringPiece::npos);
   EXPECT_EQ(e.find_last_not_of(f, 4), StringPiece::npos);
 
   EXPECT_EQ(h.find_last_not_of('x'), h.size() - 1);
@@ -533,9 +468,7 @@
   EXPECT_EQ(h.find_last_not_of('=', 2), StringPiece::npos);
   EXPECT_EQ(b.find_last_not_of('b', 1), 0);
   // empty string nonsense
-  EXPECT_EQ(d.find_last_not_of('x'), StringPiece::npos);
   EXPECT_EQ(e.find_last_not_of('x'), StringPiece::npos);
-  EXPECT_EQ(d.find_last_not_of('\0'), StringPiece::npos);
   EXPECT_EQ(e.find_last_not_of('\0'), StringPiece::npos);
 
   EXPECT_EQ(a.substr(0, 3), b);
@@ -546,33 +479,15 @@
   EXPECT_EQ(a.substr(3, 2), "de");
   // empty string nonsense
   EXPECT_EQ(a.substr(99, 2), e);
-  EXPECT_EQ(d.substr(99), e);
-  EXPECT_EQ(d.substr(0, 99), e);
-  EXPECT_EQ(d.substr(99, 99), e);
+  EXPECT_EQ(e.substr(99), e);
+  EXPECT_EQ(e.substr(0, 99), e);
+  EXPECT_EQ(e.substr(99, 99), e);
   // use of npos
   EXPECT_EQ(a.substr(0, StringPiece::npos), a);
   EXPECT_EQ(a.substr(23, StringPiece::npos), c);
   EXPECT_EQ(a.substr(StringPiece::npos, 0), e);
   EXPECT_EQ(a.substr(StringPiece::npos, 1), e);
   EXPECT_EQ(a.substr(StringPiece::npos, StringPiece::npos), e);
-
-  // Substring constructors.
-  EXPECT_EQ(StringPiece(a, 0, 3), b);
-  EXPECT_EQ(StringPiece(a, 23), c);
-  EXPECT_EQ(StringPiece(a, 23, 3), c);
-  EXPECT_EQ(StringPiece(a, 23, 99), c);
-  EXPECT_EQ(StringPiece(a, 0), a);
-  EXPECT_EQ(StringPiece(a, 3, 2), "de");
-  // empty string nonsense
-  EXPECT_EQ(StringPiece(d, 0, 99), e);
-  // Verify that they work taking an actual string, not just a StringPiece.
-  std::string a2 = a.as_string();
-  EXPECT_EQ(StringPiece(a2, 0, 3), b);
-  EXPECT_EQ(StringPiece(a2, 23), c);
-  EXPECT_EQ(StringPiece(a2, 23, 3), c);
-  EXPECT_EQ(StringPiece(a2, 23, 99), c);
-  EXPECT_EQ(StringPiece(a2, 0), a);
-  EXPECT_EQ(StringPiece(a2, 3, 2), "de");
 }
 
 TEST(StringPiece, Custom) {
@@ -647,23 +562,7 @@
   c.remove_suffix(c.size());
   EXPECT_EQ(c, e);
 
-  // set
-  c.set("foobar", 6);
-  EXPECT_EQ(c, a);
-  c.set("foobar", 0);
-  EXPECT_EQ(c, e);
-  c.set("foobar", 7);
-  EXPECT_NE(c, a);
-
-  c.set("foobar");
-  EXPECT_EQ(c, a);
-
-  c.set(static_cast<const void*>("foobar"), 6);
-  EXPECT_EQ(c, a);
-  c.set(static_cast<const void*>("foobar"), 0);
-  EXPECT_EQ(c, e);
-  c.set(static_cast<const void*>("foobar"), 7);
-  EXPECT_NE(c, a);
+  c = StringPiece("foobar", 7);
 
   // as_string
   std::string s3(a.as_string().c_str(), 7);
@@ -680,21 +579,25 @@
   }
 
   // Consume
-  a.set("foobar");
-  EXPECT_TRUE(a.Consume("foo"));
-  EXPECT_EQ(a, "bar");
-  EXPECT_FALSE(a.Consume("foo"));
-  EXPECT_FALSE(a.Consume("barbar"));
-  EXPECT_FALSE(a.Consume("ar"));
-  EXPECT_EQ(a, "bar");
+  {
+    StringPiece str("foobar");
+    EXPECT_TRUE(str.Consume("foo"));
+    EXPECT_EQ(str, "bar");
+    EXPECT_FALSE(str.Consume("foo"));
+    EXPECT_FALSE(str.Consume("barbar"));
+    EXPECT_FALSE(str.Consume("ar"));
+    EXPECT_EQ(str, "bar");
+  }
 
-  a.set("foobar");
-  EXPECT_TRUE(a.ConsumeFromEnd("bar"));
-  EXPECT_EQ(a, "foo");
-  EXPECT_FALSE(a.ConsumeFromEnd("bar"));
-  EXPECT_FALSE(a.ConsumeFromEnd("foofoo"));
-  EXPECT_FALSE(a.ConsumeFromEnd("fo"));
-  EXPECT_EQ(a, "foo");
+  {
+  StringPiece str("foobar");
+  EXPECT_TRUE(str.ConsumeFromEnd("bar"));
+  EXPECT_EQ(str, "foo");
+  EXPECT_FALSE(str.ConsumeFromEnd("bar"));
+  EXPECT_FALSE(str.ConsumeFromEnd("foofoo"));
+  EXPECT_FALSE(str.ConsumeFromEnd("fo"));
+  EXPECT_EQ(str, "foo");
+  }
 }
 
 TEST(StringPiece, Contains) {
@@ -713,10 +616,6 @@
   EXPECT_EQ(s.data(), (const char*)nullptr);
   EXPECT_EQ(s.size(), 0);
 
-  s.set(nullptr);
-  EXPECT_EQ(s.data(), (const char*)nullptr);
-  EXPECT_EQ(s.size(), 0);
-
   // .ToString() on a StringPiece with nullptr should produce the empty string.
   EXPECT_EQ("", s.ToString());
   EXPECT_EQ("", s.as_string());
diff --git a/src/google/protobuf/stubs/stringprintf.cc b/src/google/protobuf/stubs/stringprintf.cc
index 2603164..0761986 100644
--- a/src/google/protobuf/stubs/stringprintf.cc
+++ b/src/google/protobuf/stubs/stringprintf.cc
@@ -162,7 +162,7 @@
   // that accepts an array of arguments.  The best I can do is stick
   // this COMPILE_ASSERT right next to the actual statement.
 
-  GOOGLE_COMPILE_ASSERT(kStringPrintfVectorMaxArgs == 32, arg_count_mismatch);
+  static_assert(kStringPrintfVectorMaxArgs == 32, "arg_count_mismatch");
   return StringPrintf(format,
                       cstr[0], cstr[1], cstr[2], cstr[3], cstr[4],
                       cstr[5], cstr[6], cstr[7], cstr[8], cstr[9],
diff --git a/src/google/protobuf/stubs/strutil.cc b/src/google/protobuf/stubs/strutil.cc
index 2ecdb2b..84ea62e 100644
--- a/src/google/protobuf/stubs/strutil.cc
+++ b/src/google/protobuf/stubs/strutil.cc
@@ -545,7 +545,7 @@
   };
 
   size_t escaped_len = 0;
-  for (int i = 0; i < src.size(); ++i) {
+  for (StringPiece::size_type i = 0; i < src.size(); ++i) {
     unsigned char c = static_cast<unsigned char>(src[i]);
     escaped_len += c_escaped_len[c];
   }
@@ -569,7 +569,7 @@
   dest->resize(cur_dest_len + escaped_len);
   char* append_ptr = &(*dest)[cur_dest_len];
 
-  for (int i = 0; i < src.size(); ++i) {
+  for (StringPiece::size_type i = 0; i < src.size(); ++i) {
     unsigned char c = static_cast<unsigned char>(src[i]);
     switch (c) {
       case '\n': *append_ptr++ = '\\'; *append_ptr++ = 'n'; break;
@@ -1244,7 +1244,7 @@
   // platforms these days.  Just in case some system exists where DBL_DIG
   // is significantly larger -- and risks overflowing our buffer -- we have
   // this assert.
-  GOOGLE_COMPILE_ASSERT(DBL_DIG < 20, DBL_DIG_is_too_big);
+  static_assert(DBL_DIG < 20, "DBL_DIG_is_too_big");
 
   if (value == std::numeric_limits<double>::infinity()) {
     strcpy(buffer, "inf");
@@ -1362,7 +1362,7 @@
   // platforms these days.  Just in case some system exists where FLT_DIG
   // is significantly larger -- and risks overflowing our buffer -- we have
   // this assert.
-  GOOGLE_COMPILE_ASSERT(FLT_DIG < 10, FLT_DIG_is_too_big);
+  static_assert(FLT_DIG < 10, "FLT_DIG_is_too_big");
 
   if (value == std::numeric_limits<double>::infinity()) {
     strcpy(buffer, "inf");
@@ -1619,7 +1619,8 @@
   std::string tmp;
   int num_replacements = 0;
   int pos = 0;
-  for (int match_pos = s->find(substring.data(), pos, substring.length());
+  for (StringPiece::size_type match_pos =
+           s->find(substring.data(), pos, substring.length());
        match_pos != std::string::npos; pos = match_pos + substring.length(),
            match_pos = s->find(substring.data(), pos, substring.length())) {
     ++num_replacements;
diff --git a/src/google/protobuf/stubs/strutil.h b/src/google/protobuf/stubs/strutil.h
index 31c5489..84fc232 100644
--- a/src/google/protobuf/stubs/strutil.h
+++ b/src/google/protobuf/stubs/strutil.h
@@ -377,14 +377,14 @@
 // For now, long long is 64-bit on all the platforms we care about, so these
 // functions can simply pass the call to strto[u]ll.
 inline int64 strto64(const char *nptr, char **endptr, int base) {
-  GOOGLE_COMPILE_ASSERT(sizeof(int64) == sizeof(long long),
-                        sizeof_int64_is_not_sizeof_long_long);
+  static_assert(sizeof(int64) == sizeof(long long),
+                "sizeof_int64_is_not_sizeof_long_long");
   return strtoll(nptr, endptr, base);
 }
 
 inline uint64 strtou64(const char *nptr, char **endptr, int base) {
-  GOOGLE_COMPILE_ASSERT(sizeof(uint64) == sizeof(unsigned long long),
-                        sizeof_uint64_is_not_sizeof_long_long);
+  static_assert(sizeof(uint64) == sizeof(unsigned long long),
+                "sizeof_uint64_is_not_sizeof_long_long");
   return strtoull(nptr, endptr, base);
 }
 
diff --git a/src/google/protobuf/timestamp.pb.h b/src/google/protobuf/timestamp.pb.h
index a299c12..020af19 100644
--- a/src/google/protobuf/timestamp.pb.h
+++ b/src/google/protobuf/timestamp.pb.h
@@ -13,7 +13,7 @@
 #error incompatible with your Protocol Buffer headers. Please update
 #error your headers.
 #endif
-#if 3015006 < PROTOBUF_MIN_PROTOC_VERSION
+#if 3015008 < 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.
diff --git a/src/google/protobuf/type.pb.h b/src/google/protobuf/type.pb.h
index 362f7cd..e6a93f1 100644
--- a/src/google/protobuf/type.pb.h
+++ b/src/google/protobuf/type.pb.h
@@ -13,7 +13,7 @@
 #error incompatible with your Protocol Buffer headers. Please update
 #error your headers.
 #endif
-#if 3015006 < PROTOBUF_MIN_PROTOC_VERSION
+#if 3015008 < 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.
diff --git a/src/google/protobuf/util/internal/object_writer.cc b/src/google/protobuf/util/internal/object_writer.cc
index b7667b6..4dabd37 100644
--- a/src/google/protobuf/util/internal/object_writer.cc
+++ b/src/google/protobuf/util/internal/object_writer.cc
@@ -74,7 +74,7 @@
       break;
     }
     case DataPiece::TYPE_BYTES: {
-      ow->RenderBytes(name, data.ToBytes().ValueOrDie());
+      ow->RenderBytes(name, data.ToBytes().value());
       break;
     }
     case DataPiece::TYPE_NULL: {
diff --git a/src/google/protobuf/util/internal/proto_writer.cc b/src/google/protobuf/util/internal/proto_writer.cc
index ff4fe54..717cee4 100644
--- a/src/google/protobuf/util/internal/proto_writer.cc
+++ b/src/google/protobuf/util/internal/proto_writer.cc
@@ -253,7 +253,7 @@
                                CodedOutputStream* stream) {
   util::StatusOr<std::string> c = data.ToBytes();
   if (c.ok()) {
-    WireFormatLite::WriteBytes(field_number, c.ValueOrDie(), stream);
+    WireFormatLite::WriteBytes(field_number, c.value(), stream);
   }
   return c.status();
 }
diff --git a/src/google/protobuf/util/internal/protostream_objectwriter.cc b/src/google/protobuf/util/internal/protostream_objectwriter.cc
index f82c414..9878826 100644
--- a/src/google/protobuf/util/internal/protostream_objectwriter.cc
+++ b/src/google/protobuf/util/internal/protostream_objectwriter.cc
@@ -436,7 +436,7 @@
     StrAppend(&value_storage_, value_.str());
     value_ = DataPiece(value_storage_, value_.use_strict_base64_decoding());
   } else if (value_.type() == DataPiece::TYPE_BYTES) {
-    value_storage_ = value_.ToBytes().ValueOrDie();
+    value_storage_ = value_.ToBytes().value();
     value_ =
         DataPiece(value_storage_, true, value_.use_strict_base64_decoding());
   }
diff --git a/src/google/protobuf/wrappers.pb.h b/src/google/protobuf/wrappers.pb.h
index 6ce1c48..9c7d0a0 100644
--- a/src/google/protobuf/wrappers.pb.h
+++ b/src/google/protobuf/wrappers.pb.h
@@ -13,7 +13,7 @@
 #error incompatible with your Protocol Buffer headers. Please update
 #error your headers.
 #endif
-#if 3015006 < PROTOBUF_MIN_PROTOC_VERSION
+#if 3015008 < 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.