Merge tag 'refs/tags/sync-piper' into sync-stage
diff --git a/Makefile.am b/Makefile.am
index cab595d..ddbe08b 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -280,6 +280,7 @@
   java/core/generate-sources-build.xml                                             \
   java/core/generate-test-sources-build.xml                                        \
   java/core/pom.xml                                                                \
+  java/core/pom_template.xml                                                       \
   java/core/src/main/java/com/google/protobuf/AbstractMessage.java                 \
   java/core/src/main/java/com/google/protobuf/AbstractMessageLite.java             \
   java/core/src/main/java/com/google/protobuf/AbstractParser.java                  \
@@ -567,6 +568,7 @@
   java/lite/generate-test-sources-build.xml                                        \
   java/lite/lite.awk                                                               \
   java/lite/pom.xml                                                                \
+  java/lite/pom_template.xml                                                       \
   java/lite/process-lite-sources-build.xml                                         \
   java/lite/src/test/java/com/google/protobuf/LiteTest.java                        \
   java/lite/src/test/java/com/google/protobuf/Proto2MessageLiteInfoFactory.java    \
@@ -574,11 +576,11 @@
   java/pom.xml                                                                     \
   java/util/BUILD                                                                  \
   java/util/pom.xml                                                                \
+  java/util/pom_template.xml                                                       \
   java/util/src/main/java/com/google/protobuf/util/Durations.java                  \
   java/util/src/main/java/com/google/protobuf/util/FieldMaskTree.java              \
   java/util/src/main/java/com/google/protobuf/util/FieldMaskUtil.java              \
   java/util/src/main/java/com/google/protobuf/util/JsonFormat.java                 \
-  java/util/src/main/java/com/google/protobuf/util/TimeUtil.java                   \
   java/util/src/main/java/com/google/protobuf/util/Structs.java                    \
   java/util/src/main/java/com/google/protobuf/util/Timestamps.java                 \
   java/util/src/main/java/com/google/protobuf/util/Values.java                     \
@@ -586,7 +588,6 @@
   java/util/src/test/java/com/google/protobuf/util/FieldMaskUtilTest.java          \
   java/util/src/test/java/com/google/protobuf/util/JsonFormatTest.java             \
   java/util/src/test/java/com/google/protobuf/util/StructsTest.java                \
-  java/util/src/test/java/com/google/protobuf/util/TimeUtilTest.java               \
   java/util/src/test/java/com/google/protobuf/util/ValuesTest.java                 \
   java/util/src/test/proto/com/google/protobuf/util/json_test.proto
 
@@ -801,6 +802,7 @@
 php_EXTRA_DIST=                                                       \
   composer.json                                                       \
   php/README.md                                                       \
+  php/REFCOUNTING.md                                                  \
   php/composer.json                                                   \
   php/ext/google/protobuf/arena.c                                     \
   php/ext/google/protobuf/arena.h                                     \
@@ -1136,6 +1138,7 @@
   ruby/ext/google/protobuf_c/ruby-upb.h                                      \
   ruby/ext/google/protobuf_c/wrap_memcpy.c                                   \
   ruby/google-protobuf.gemspec                                               \
+  ruby/lib/google/protobuf/descriptor_dsl.rb                                 \
   ruby/lib/google/protobuf/message_exts.rb                                   \
   ruby/lib/google/protobuf/repeated_field.rb                                 \
   ruby/lib/google/protobuf/well_known_types.rb                               \
@@ -1426,7 +1429,8 @@
   third_party/zlib.BUILD                 \
   third_party/wyhash/LICENSE             \
   third_party/wyhash/wyhash.h            \
-  util/python/BUILD
+  util/python/BUILD                      \
+  internal.bzl
 
 
 # Deletes all the files generated by autogen.sh.
diff --git a/Protobuf-C++.podspec b/Protobuf-C++.podspec
index 13adedd..2e81a7c 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.8'
+  s.version  = '3.17.3'
   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/autogen.sh b/autogen.sh
index d00d217..105bf09 100755
--- a/autogen.sh
+++ b/autogen.sh
@@ -30,8 +30,12 @@
 
 # The absence of a m4 directory in googletest causes autoreconf to fail when
 # building under the CentOS docker image. It's a warning in regular build on
-# Ubuntu/gLinux as well.
-mkdir -p third_party/googletest/m4
+# Ubuntu/gLinux as well. (This is only needed if git submodules have been
+# initialized, which is typically only needed for testing; see the installation
+# instructions for details.)
+if test -d third_party/googletest; then
+  mkdir -p third_party/googletest/m4
+fi
 
 # TODO(kenton):  Remove the ",no-obsolete" part and fix the resulting warnings.
 autoreconf -f -i -Wall,no-obsolete
diff --git a/benchmarks/java/pom.xml b/benchmarks/java/pom.xml
index 570bd66..c0dc940 100644
--- a/benchmarks/java/pom.xml
+++ b/benchmarks/java/pom.xml
@@ -22,7 +22,7 @@
     <dependency>
       <groupId>com.google.caliper</groupId>
       <artifactId>caliper</artifactId>
-      <version>1.0-beta-2</version>
+      <version>1.0-beta-3</version>
     </dependency>
   </dependencies>
 
diff --git a/benchmarks/util/result_parser.py b/benchmarks/util/result_parser.py
index b09f387..896f47a 100644
--- a/benchmarks/util/result_parser.py
+++ b/benchmarks/util/result_parser.py
@@ -1,5 +1,6 @@
 # This import depends on the automake rule protoc_middleman, please make sure
 # protoc_middleman has been built before run this file.
+import argparse
 import json
 import re
 import os.path
@@ -298,3 +299,39 @@
     __parse_php_result(php_c_file, "php")
 
   return __results
+
+if __name__ == "__main__":
+  parser = argparse.ArgumentParser()
+  parser.add_argument("-cpp", "--cpp_input_file",
+                      help="The CPP benchmark result file's name",
+                      default="")
+  parser.add_argument("-java", "--java_input_file",
+                      help="The Java benchmark result file's name",
+                      default="")
+  parser.add_argument("-python", "--python_input_file",
+                      help="The Python benchmark result file's name",
+                      default="")
+  parser.add_argument("-go", "--go_input_file",
+                      help="The golang benchmark result file's name",
+                      default="")
+  parser.add_argument("-node", "--node_input_file",
+                      help="The node.js benchmark result file's name",
+                      default="")
+  parser.add_argument("-php", "--php_input_file",
+                      help="The pure php benchmark result file's name",
+                      default="")
+  parser.add_argument("-php_c", "--php_c_input_file",
+                      help="The php with c ext benchmark result file's name",
+                      default="")
+  args = parser.parse_args()
+
+  results = get_result_from_file(
+      cpp_file=args.cpp_input_file,
+      java_file=args.java_input_file,
+      python_file=args.python_input_file,
+      go_file=args.go_input_file,
+      node_file=args.node_input_file,
+      php_file=args.php_input_file,
+      php_c_file=args.php_c_input_file,
+  )
+  print(json.dumps(results, indent=2))
diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt
index 5c3b6e4..61a5c3d 100644
--- a/cmake/CMakeLists.txt
+++ b/cmake/CMakeLists.txt
@@ -193,8 +193,10 @@
 endif (protobuf_BUILD_SHARED_LIBS)
 
 if (MSVC)
-  # Build with multiple processes
-  add_definitions(/MP)
+  if (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
+    # Build with multiple processes
+    add_definitions(/MP)
+  endif()
   # MSVC warning suppressions
   add_definitions(
     /wd4018 # 'expression' : signed/unsigned mismatch
@@ -222,12 +224,14 @@
   # Suppress linker warnings about files with no symbols defined.
   set(CMAKE_STATIC_LINKER_FLAGS "${CMAKE_STATIC_LINKER_FLAGS} /ignore:4221")
 
-  # Configure Resource Compiler
-  enable_language(RC)
-  # use English language (0x409) in resource compiler
-  set(rc_flags "/l0x409")
-  # fix rc.exe invocations because of usage of add_definitions()
-  set(CMAKE_RC_COMPILE_OBJECT "<CMAKE_RC_COMPILER> ${rc_flags} <DEFINES> /fo<OBJECT> <SOURCE>")
+  if (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
+    # Configure Resource Compiler
+    enable_language(RC)
+    # use English language (0x409) in resource compiler
+    set(rc_flags "/l0x409")
+    # fix rc.exe invocations because of usage of add_definitions()
+    set(CMAKE_RC_COMPILE_OBJECT "<CMAKE_RC_COMPILER> ${rc_flags} <DEFINES> /fo<OBJECT> <SOURCE>")
+  endif()
 
   configure_file(version.rc.in ${CMAKE_CURRENT_BINARY_DIR}/version.rc @ONLY)
 endif (MSVC)
diff --git a/cmake/extract_includes.bat.in b/cmake/extract_includes.bat.in
index 05512da..990a57f 100644
--- a/cmake/extract_includes.bat.in
+++ b/cmake/extract_includes.bat.in
@@ -46,11 +46,15 @@
 copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\empty.pb.h" include\google\protobuf\empty.pb.h
 copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\extension_set.h" include\google\protobuf\extension_set.h
 copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\extension_set_inl.h" include\google\protobuf\extension_set_inl.h
+copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\field_access_listener.h" include\google\protobuf\field_access_listener.h
 copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\field_mask.pb.h" include\google\protobuf\field_mask.pb.h
 copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\generated_enum_reflection.h" include\google\protobuf\generated_enum_reflection.h
 copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\generated_enum_util.h" include\google\protobuf\generated_enum_util.h
 copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\generated_message_reflection.h" include\google\protobuf\generated_message_reflection.h
 copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\generated_message_table_driven.h" include\google\protobuf\generated_message_table_driven.h
+copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\generated_message_tctable_decl.h" include\google\protobuf\generated_message_tctable_decl.h
+copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\generated_message_tctable_impl.h" include\google\protobuf\generated_message_tctable_impl.h
+copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\generated_message_tctable_impl.inc" include\google\protobuf\generated_message_tctable_impl.inc
 copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\generated_message_util.h" include\google\protobuf\generated_message_util.h
 copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\has_bits.h" include\google\protobuf\has_bits.h
 copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\implicit_weak_message.h" include\google\protobuf\implicit_weak_message.h
diff --git a/cmake/libprotobuf-lite.cmake b/cmake/libprotobuf-lite.cmake
index 6d325d5..e6fab3b 100644
--- a/cmake/libprotobuf-lite.cmake
+++ b/cmake/libprotobuf-lite.cmake
@@ -57,7 +57,7 @@
   ${protobuf_source_dir}/src/google/protobuf/wire_format_lite.h
 )
 
-if (MSVC)
+if (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
 set(libprotobuf_lite_rc_files
   ${CMAKE_CURRENT_BINARY_DIR}/version.rc
 )
diff --git a/cmake/libprotobuf.cmake b/cmake/libprotobuf.cmake
index 479e362..f5a70be 100644
--- a/cmake/libprotobuf.cmake
+++ b/cmake/libprotobuf.cmake
@@ -108,7 +108,7 @@
   ${protobuf_source_dir}/src/google/protobuf/wrappers.pb.h
 )
 
-if (MSVC)
+if (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
 set(libprotobuf_rc_files
   ${CMAKE_CURRENT_BINARY_DIR}/version.rc
 )
diff --git a/cmake/libprotoc.cmake b/cmake/libprotoc.cmake
index b70191f..a6f7919 100644
--- a/cmake/libprotoc.cmake
+++ b/cmake/libprotoc.cmake
@@ -163,7 +163,7 @@
   ${protobuf_source_dir}/src/google/protobuf/compiler/zip_writer.h
 )
 
-if (MSVC)
+if (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
 set(libprotoc_rc_files
   ${CMAKE_CURRENT_BINARY_DIR}/version.rc
 )
diff --git a/cmake/protoc.cmake b/cmake/protoc.cmake
index f90e525..c86d662 100644
--- a/cmake/protoc.cmake
+++ b/cmake/protoc.cmake
@@ -2,7 +2,7 @@
   ${protobuf_source_dir}/src/google/protobuf/compiler/main.cc
 )
 
-if (MSVC)
+if (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
 set(protoc_rc_files
   ${CMAKE_CURRENT_BINARY_DIR}/version.rc
 )
diff --git a/configure.ac b/configure.ac
index 2b575ef..a3309b7 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.8],[protobuf@googlegroups.com],[protobuf])
+AC_INIT([Protocol Buffers],[3.17.3],[protobuf@googlegroups.com],[protobuf])
 
 AM_MAINTAINER_MODE([enable])
 
@@ -125,7 +125,7 @@
   [have_ld_version_script=yes; AC_MSG_RESULT(yes)],
   [have_ld_version_script=no; AC_MSG_RESULT(no)])
 LDFLAGS=$save_LDFLAGS
-AM_CONDITIONAL([HAVE_LD_VERSION_SCRIPT], [test "$have_ld_version_script" == "yes"])
+AM_CONDITIONAL([HAVE_LD_VERSION_SCRIPT], [test "$have_ld_version_script" = "yes"])
 
 # Checks for header files.
 AC_HEADER_STDC
diff --git a/java/core/src/main/java/com/google/protobuf/GeneratedMessageV3.java b/java/core/src/main/java/com/google/protobuf/GeneratedMessageV3.java
index 86f88a0..f54b123 100644
--- a/java/core/src/main/java/com/google/protobuf/GeneratedMessageV3.java
+++ b/java/core/src/main/java/com/google/protobuf/GeneratedMessageV3.java
@@ -3068,6 +3068,14 @@
     return (Extension<MessageType, T>) extension;
   }
 
+  protected static boolean isStringEmpty(final Object value) {
+    if (value instanceof String) {
+      return ((String) value).isEmpty();
+    } else {
+      return ((ByteString) value).isEmpty();
+    }
+  }
+
   protected static int computeStringSize(final int fieldNumber, final Object value) {
     if (value instanceof String) {
       return CodedOutputStream.computeStringSize(fieldNumber, (String) value);
diff --git a/java/core/src/test/java/com/google/protobuf/TestUtil.java b/java/core/src/test/java/com/google/protobuf/TestUtil.java
index d42593a..936a525 100644
--- a/java/core/src/test/java/com/google/protobuf/TestUtil.java
+++ b/java/core/src/test/java/com/google/protobuf/TestUtil.java
@@ -3758,7 +3758,7 @@
 
   /** @param filePath The path relative to {@link #getTestDataDir}. */
   public static String readTextFromFile(String filePath) {
-    return readBytesFromFile(filePath).toStringUtf8();
+    return readBytesFromFile(filePath).toStringUtf8().replace(System.getProperty("line.separator"), "\n");
   }
 
   private static File getTestDataDir() {
diff --git a/java/kotlin/src/main/kotlin/com/google/protobuf/ExtensionList.kt b/java/kotlin/src/main/kotlin/com/google/protobuf/ExtensionList.kt
index 37e958e..d8982eb 100644
--- a/java/kotlin/src/main/kotlin/com/google/protobuf/ExtensionList.kt
+++ b/java/kotlin/src/main/kotlin/com/google/protobuf/ExtensionList.kt
@@ -40,7 +40,7 @@
  */
 class ExtensionList<E, M : MessageLite> @OnlyForUseByGeneratedProtoCode constructor(
   val extension: ExtensionLite<M, List<E>>,
-  @JvmField private val delegate: List<E>
+  private val delegate: List<E>
 ) : List<E> by delegate {
   override fun iterator(): Iterator<E> = UnmodifiableIterator(delegate.iterator())
 
diff --git a/java/kotlin/src/test/kotlin/com/google/protobuf/Proto2Test.kt b/java/kotlin/src/test/kotlin/com/google/protobuf/Proto2Test.kt
index ad7f242..65f0324 100644
--- a/java/kotlin/src/test/kotlin/com/google/protobuf/Proto2Test.kt
+++ b/java/kotlin/src/test/kotlin/com/google/protobuf/Proto2Test.kt
@@ -495,12 +495,12 @@
         this[UnittestProto.repeatedBytesExtension] += toBytes("316")
         this[UnittestProto.repeatedGroupExtension] += repeatedGroupExtension { a = 317 }
         this[UnittestProto.repeatedNestedMessageExtension] +=
-          TestAllTypesKt.nestedMessage { bb = 318 }
+	  TestAllTypesKt.nestedMessage { bb = 318 }
         this[UnittestProto.repeatedForeignMessageExtension] += foreignMessage { c = 319 }
         this[UnittestProto.repeatedImportMessageExtension] +=
           ImportMessage.newBuilder().setD(320).build()
         this[UnittestProto.repeatedLazyMessageExtension] +=
-          TestAllTypesKt.nestedMessage { bb = 327 }
+	  TestAllTypesKt.nestedMessage { bb = 327 }
         this[UnittestProto.repeatedNestedEnumExtension] += NestedEnum.BAZ
         this[UnittestProto.repeatedForeignEnumExtension] += ForeignEnum.FOREIGN_BAZ
         this[UnittestProto.repeatedImportEnumExtension] += ImportEnum.IMPORT_BAZ
diff --git a/js/commonjs/export.js b/js/commonjs/export.js
index a93ee92..a9932e9 100644
--- a/js/commonjs/export.js
+++ b/js/commonjs/export.js
@@ -5,8 +5,6 @@
  * the google-protobuf.js file that we build at distribution time.
  */
 
-// Include a dummy provide statement so that closurebuilder.py does not skip over this
-// file.
 goog.provide('jspb.Export');
 
 goog.require('goog.object');
diff --git a/js/commonjs/export_asserts.js b/js/commonjs/export_asserts.js
index ad9446c..fa6e795 100644
--- a/js/commonjs/export_asserts.js
+++ b/js/commonjs/export_asserts.js
@@ -6,8 +6,6 @@
  * closure_asserts_commonjs.js that is only used at testing time.
  */
 
-// Include a dummy provide statement so that closurebuilder.py does not skip over this
-// file.
 goog.provide('jspb.ExportAsserts');
 
 goog.require('goog.testing.asserts');
diff --git a/js/commonjs/export_testdeps.js b/js/commonjs/export_testdeps.js
index 96d3f34..51d868e 100644
--- a/js/commonjs/export_testdeps.js
+++ b/js/commonjs/export_testdeps.js
@@ -7,8 +7,6 @@
  * export_asserts.js.
  */
 
-// Include a dummy provide statement so that closurebuilder.py does not skip over this
-// file.
 goog.provide('jspb.ExportTestDeps');
 
 goog.require('goog.crypt.base64');
diff --git a/js/compatibility_tests/v3.0.0/test.sh b/js/compatibility_tests/v3.0.0/test.sh
index 9d58f30..5b92ed1 100755
--- a/js/compatibility_tests/v3.0.0/test.sh
+++ b/js/compatibility_tests/v3.0.0/test.sh
@@ -53,8 +53,20 @@
 done
 cp commonjs/{jasmine.json,import_test.js} commonjs_out/
 mkdir -p commonjs_out/test_node_modules
-../../node_modules/google-closure-library/closure/bin/calcdeps.py -i commonjs/export_asserts.js -p . -p ../../node_modules/google-closure-library/closure -o compiled --compiler_jar ../../node_modules/google-closure-compiler/compiler.jar > commonjs_out/test_node_modules/closure_asserts_commonjs.js
-../../node_modules/google-closure-library/closure/bin/calcdeps.py -i commonjs/export_testdeps.js -p ../.. -p ../../node_modules/google-closure-library/closure -o compiled --compiler_jar ../../node_modules/google-closure-compiler/compiler.jar > commonjs_out/test_node_modules/testdeps_commonjs.js
+../../node_modules/.bin/google-closure-compiler \
+  --entry_point=commonjs/export_asserts.js \
+  --js=commonjs/export_asserts.js \
+  --js=../../node_modules/google-closure-library/closure/goog/**.js \
+  --js=../../node_modules/google-closure-library/third_party/closure/goog/**.js \
+  > commonjs_out/test_node_modules/closure_asserts_commonjs.js
+../../node_modules/.bin/google-closure-compiler \
+  --entry_point=commonjs/export_testdeps.js \
+  --js=commonjs/export_testdeps.js \
+  --js=../../binary/*.js \
+  --js=!../../binary/*_test.js \
+  --js=../../node_modules/google-closure-library/closure/goog/**.js \
+  --js=../../node_modules/google-closure-library/third_party/closure/goog/**.js \
+  > commonjs_out/test_node_modules/testdeps_commonjs.js
 cp ../../google-protobuf.js commonjs_out/test_node_modules
 cp -r ../../commonjs_out/node_modules commonjs_out
 
diff --git a/js/gulpfile.js b/js/gulpfile.js
index 8137b90..dea5f41 100644
--- a/js/gulpfile.js
+++ b/js/gulpfile.js
@@ -140,21 +140,31 @@
 });
 
 
-function getClosureBuilderCommand(exportsFile, outputFile) {
-  return './node_modules/google-closure-library/closure/bin/build/closurebuilder.py ' +
-  '--root node_modules ' +
-  '-o compiled ' +
-  '--compiler_jar node_modules/google-closure-compiler-java/compiler.jar ' +
-  '-i ' + exportsFile + ' ' +
-  'map.js message.js binary/arith.js binary/constants.js binary/decoder.js ' +
-  'binary/encoder.js binary/reader.js binary/utils.js binary/writer.js ' +
-  exportsFile  + ' > ' + outputFile;
+function getClosureCompilerCommand(exportsFile, outputFile) {
+  const closureLib = 'node_modules/google-closure-library';
+  return [
+    'node_modules/.bin/google-closure-compiler',
+    `--js=${closureLib}/closure/goog/**.js`,
+    `--js=${closureLib}/third_party/closure/goog/**.js`,
+    '--js=map.js',
+    '--js=message.js',
+    '--js=binary/arith.js',
+    '--js=binary/constants.js',
+    '--js=binary/decoder.js',
+    '--js=binary/encoder.js',
+    '--js=binary/reader.js',
+    '--js=binary/utils.js',
+    '--js=binary/writer.js',
+    `--js=${exportsFile}`,
+    `--entry_point=${exportsFile}`,
+    `> ${outputFile}`
+  ].join(' ');
 }
 
 gulp.task('dist', gulp.series(['genproto_wellknowntypes'], function(cb) {
   // TODO(haberman): minify this more aggressively.
   // Will require proper externs/exports.
-  exec(getClosureBuilderCommand('commonjs/export.js', 'google-protobuf.js'),
+  exec(getClosureCompilerCommand('commonjs/export.js', 'google-protobuf.js'),
        function (err, stdout, stderr) {
     console.log(stdout);
     console.log(stderr);
@@ -164,7 +174,7 @@
 
 gulp.task('commonjs_asserts', function (cb) {
   exec('mkdir -p commonjs_out/test_node_modules && ' +
-       getClosureBuilderCommand(
+       getClosureCompilerCommand(
            'commonjs/export_asserts.js',
            'commonjs_out/test_node_modules/closure_asserts_commonjs.js'),
        function (err, stdout, stderr) {
@@ -176,7 +186,7 @@
 
 gulp.task('commonjs_testdeps', function (cb) {
   exec('mkdir -p commonjs_out/test_node_modules && ' +
-       getClosureBuilderCommand(
+       getClosureCompilerCommand(
            'commonjs/export_testdeps.js',
            'commonjs_out/test_node_modules/testdeps_commonjs.js'),
        function (err, stdout, stderr) {
@@ -229,7 +239,7 @@
         ],
         function(cb) {
           exec(
-              './node_modules/google-closure-library/closure/bin/build/depswriter.py binary/arith.js binary/constants.js binary/decoder.js binary/encoder.js binary/reader.js binary/utils.js binary/writer.js debug.js map.js message.js node_loader.js test_bootstrap.js > deps.js',
+              './node_modules/.bin/closure-make-deps --closure-path=. --file=node_modules/google-closure-library/closure/goog/deps.js binary/arith.js binary/constants.js binary/decoder.js binary/encoder.js binary/reader.js binary/utils.js binary/writer.js debug.js map.js message.js node_loader.js test_bootstrap.js > deps.js',
               function(err, stdout, stderr) {
                 console.log(stdout);
                 console.log(stderr);
diff --git a/js/package.json b/js/package.json
index 19812c0..8121aac 100644
--- a/js/package.json
+++ b/js/package.json
@@ -1,6 +1,6 @@
 {
   "name": "google-protobuf",
-  "version": "3.15.8",
+  "version": "3.17.3",
   "description": "Protocol Buffers for JavaScript",
   "main": "google-protobuf.js",
   "files": [
@@ -10,6 +10,7 @@
   "devDependencies": {
     "glob": "~7.1.4",
     "google-closure-compiler": "~20190819.0.0",
+    "google-closure-deps": "^20210406.0.0",
     "google-closure-library": "~20190819.0.0",
     "gulp": "~4.0.2",
     "jasmine": "~3.4.0"
diff --git a/protobuf_version.bzl b/protobuf_version.bzl
new file mode 100644
index 0000000..dd1f797
--- /dev/null
+++ b/protobuf_version.bzl
@@ -0,0 +1 @@
+PROTOBUF_VERSION = '3.17.3'
diff --git a/python/google/protobuf/__init__.py b/python/google/protobuf/__init__.py
index 4607bec..496df6a 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.8'
+__version__ = '3.17.3'
diff --git a/python/google/protobuf/internal/json_format_test.py b/python/google/protobuf/internal/json_format_test.py
index 4310115..672a9b4 100755
--- a/python/google/protobuf/internal/json_format_test.py
+++ b/python/google/protobuf/internal/json_format_test.py
@@ -1119,6 +1119,30 @@
         'Failed to parse value field: Struct must be in a dict which is 1234',
         json_format.Parse, text, message)
 
+  def testTimestampInvalidStringValue(self):
+    message = json_format_proto3_pb2.TestTimestamp()
+    text = '{"value": {"foo": 123}}'
+    self.assertRaisesRegexp(
+        json_format.ParseError,
+        r"Timestamp JSON value not a string: {u?'foo': 123}",
+        json_format.Parse, text, message)
+
+  def testDurationInvalidStringValue(self):
+    message = json_format_proto3_pb2.TestDuration()
+    text = '{"value": {"foo": 123}}'
+    self.assertRaisesRegexp(
+        json_format.ParseError,
+        r"Duration JSON value not a string: {u?'foo': 123}",
+        json_format.Parse, text, message)
+
+  def testFieldMaskInvalidStringValue(self):
+    message = json_format_proto3_pb2.TestFieldMask()
+    text = '{"value": {"foo": 123}}'
+    self.assertRaisesRegexp(
+        json_format.ParseError,
+        r"FieldMask JSON value not a string: {u?'foo': 123}",
+        json_format.Parse, text, message)
+
   def testInvalidAny(self):
     message = any_pb2.Any()
     text = '{"@type": "type.googleapis.com/google.protobuf.Int32Value"}'
@@ -1217,7 +1241,7 @@
   def testParseDictUnknownValueType(self):
     class UnknownClass(object):
 
-      def __str__(self):
+      def __repr__(self):
         return 'v'
     message = json_format_proto3_pb2.TestValue()
     self.assertRaisesRegexp(
diff --git a/python/google/protobuf/internal/python_protobuf.cc b/python/google/protobuf/internal/python_protobuf.cc
deleted file mode 100644
index e823bf2..0000000
--- a/python/google/protobuf/internal/python_protobuf.cc
+++ /dev/null
@@ -1,59 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc.  All rights reserved.
-// https://developers.google.com/protocol-buffers/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// Author: qrczak@google.com (Marcin Kowalczyk)
-
-#include <google/protobuf/python/python_protobuf.h>
-
-namespace google {
-namespace protobuf {
-namespace python {
-
-static const Message* GetCProtoInsidePyProtoStub(PyObject* msg) { return NULL; }
-static Message* MutableCProtoInsidePyProtoStub(PyObject* msg) { return NULL; }
-
-// This is initialized with a default, stub implementation.
-// If python-google.protobuf.cc is loaded, the function pointer is overridden
-// with a full implementation.
-const Message* (*GetCProtoInsidePyProtoPtr)(PyObject* msg) =
-    GetCProtoInsidePyProtoStub;
-Message* (*MutableCProtoInsidePyProtoPtr)(PyObject* msg) =
-    MutableCProtoInsidePyProtoStub;
-
-const Message* GetCProtoInsidePyProto(PyObject* msg) {
-  return GetCProtoInsidePyProtoPtr(msg);
-}
-Message* MutableCProtoInsidePyProto(PyObject* msg) {
-  return MutableCProtoInsidePyProtoPtr(msg);
-}
-
-}  // namespace python
-}  // namespace protobuf
-}  // namespace google
diff --git a/python/google/protobuf/internal/well_known_types.py b/python/google/protobuf/internal/well_known_types.py
index 6f55d6b..56659ac 100644
--- a/python/google/protobuf/internal/well_known_types.py
+++ b/python/google/protobuf/internal/well_known_types.py
@@ -143,6 +143,9 @@
     Raises:
       ValueError: On parsing problems.
     """
+    if not isinstance(value, six.string_types):
+      raise ValueError(
+          'Timestamp JSON value not a string: {!r}'.format(value))
     timezone_offset = value.find('Z')
     if timezone_offset == -1:
       timezone_offset = value.find('+')
@@ -303,6 +306,9 @@
     Raises:
       ValueError: On parsing problems.
     """
+    if not isinstance(value, six.string_types):
+      raise ValueError(
+          'Duration JSON value not a string: {!r}'.format(value))
     if len(value) < 1 or value[-1] != 's':
       raise ValueError(
           'Duration must end with letter "s": {0}.'.format(value))
@@ -428,6 +434,9 @@
 
   def FromJsonString(self, value):
     """Converts string to FieldMask according to proto3 JSON spec."""
+    if not isinstance(value, six.string_types):
+      raise ValueError(
+          'FieldMask JSON value not a string: {!r}'.format(value))
     self.Clear()
     if value:
       for path in value.split(','):
diff --git a/python/google/protobuf/python_protobuf.h b/python/google/protobuf/python_protobuf.h
deleted file mode 100644
index 8db1ffb..0000000
--- a/python/google/protobuf/python_protobuf.h
+++ /dev/null
@@ -1,57 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc.  All rights reserved.
-// https://developers.google.com/protocol-buffers/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// Author: qrczak@google.com (Marcin Kowalczyk)
-//
-// This module exposes the C proto inside the given Python proto, in
-// case the Python proto is implemented with a C proto.
-
-#ifndef GOOGLE_PROTOBUF_PYTHON_PYTHON_PROTOBUF_H__
-#define GOOGLE_PROTOBUF_PYTHON_PYTHON_PROTOBUF_H__
-
-#include <Python.h>
-
-namespace google {
-namespace protobuf {
-
-class Message;
-
-namespace python {
-
-// Return the pointer to the C proto inside the given Python proto,
-// or NULL when this is not a Python proto implemented with a C proto.
-const Message* GetCProtoInsidePyProto(PyObject* msg);
-Message* MutableCProtoInsidePyProto(PyObject* msg);
-
-}  // namespace python
-}  // namespace protobuf
-}  // namespace google
-
-#endif  // GOOGLE_PROTOBUF_PYTHON_PYTHON_PROTOBUF_H__
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 50fea74..0129741 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -18,7 +18,7 @@
 PTHREAD_DEF =
 endif
 
-PROTOBUF_VERSION = 26:8:0
+PROTOBUF_VERSION = 28:3:0
 
 if GCC
 # Turn on all warnings except for sign comparison (we ignore sign comparison
@@ -101,6 +101,9 @@
   google/protobuf/generated_enum_util.h                          \
   google/protobuf/generated_message_reflection.h                 \
   google/protobuf/generated_message_table_driven.h               \
+  google/protobuf/generated_message_tctable_decl.h               \
+  google/protobuf/generated_message_tctable_impl.h               \
+  google/protobuf/generated_message_tctable_impl.inc             \
   google/protobuf/generated_message_util.h                       \
   google/protobuf/has_bits.h                                     \
   google/protobuf/implicit_weak_message.h                        \
@@ -206,7 +209,6 @@
   google/protobuf/arena.cc                                     \
   google/protobuf/arenastring.cc                               \
   google/protobuf/extension_set.cc                             \
-  google/protobuf/field_access_listener.cc                     \
   google/protobuf/generated_enum_util.cc                       \
   google/protobuf/generated_message_util.cc                    \
   google/protobuf/generated_message_table_driven_lite.h        \
@@ -242,6 +244,7 @@
   google/protobuf/dynamic_message.cc                           \
   google/protobuf/empty.pb.cc                                  \
   google/protobuf/extension_set_heavy.cc                       \
+  google/protobuf/field_access_listener.cc                     \
   google/protobuf/field_mask.pb.cc                             \
   google/protobuf/generated_message_reflection.cc              \
   google/protobuf/generated_message_table_driven_lite.h        \
@@ -898,7 +901,9 @@
 no_warning_test.cc:
 	echo "// Generated from Makefile.am" > no_warning_test.cc
 	for FILE in $(nobase_include_HEADERS); do \
-    echo "#include <$${FILE}>" >> no_warning_test.cc; \
+          if [[ $$FILE != *.inc ]]; then \
+	    echo "#include <$${FILE}>" >> no_warning_test.cc; \
+	  fi \
 	done
 	echo "int main(int, char**) { return 0; }" >> no_warning_test.cc
 
diff --git a/src/google/protobuf/any.cc b/src/google/protobuf/any.cc
index 029ba0d..955dd80 100644
--- a/src/google/protobuf/any.cc
+++ b/src/google/protobuf/any.cc
@@ -41,18 +41,19 @@
 namespace protobuf {
 namespace internal {
 
-bool AnyMetadata::PackFrom(const Message& message) {
-  return PackFrom(message, kTypeGoogleApisComPrefix);
+bool AnyMetadata::PackFrom(Arena* arena, const Message& message) {
+  return PackFrom(arena, message, kTypeGoogleApisComPrefix);
 }
 
-bool AnyMetadata::PackFrom(const Message& message,
+bool AnyMetadata::PackFrom(Arena* arena,
+                           const Message& message,
                            StringPiece type_url_prefix) {
   type_url_->Set(
       &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyString(),
       GetTypeUrl(message.GetDescriptor()->full_name(), type_url_prefix),
-      nullptr);
+      arena);
   return message.SerializeToString(
-      value_->Mutable(ArenaStringPtr::EmptyDefault{}, nullptr));
+      value_->Mutable(ArenaStringPtr::EmptyDefault{}, arena));
 }
 
 bool AnyMetadata::UnpackTo(Message* message) const {
diff --git a/src/google/protobuf/any.h b/src/google/protobuf/any.h
index 684fbf1..3ec8294 100644
--- a/src/google/protobuf/any.h
+++ b/src/google/protobuf/any.h
@@ -67,12 +67,12 @@
   // The resulted type URL will be "type.googleapis.com/<message_full_name>".
   // Returns false if serializing the message failed.
   template <typename T>
-  bool PackFrom(const T& message) {
-    return InternalPackFrom(message, kTypeGoogleApisComPrefix,
+  bool PackFrom(Arena* arena, const T& message) {
+    return InternalPackFrom(arena, message, kTypeGoogleApisComPrefix,
                             T::FullMessageName());
   }
 
-  bool PackFrom(const Message& message);
+  bool PackFrom(Arena* arena, const Message& message);
 
   // Packs a message using the given type URL prefix. The type URL will be
   // constructed by concatenating the message type's full name to the prefix
@@ -82,11 +82,11 @@
   // URL: "type.googleapis.com/<message_full_name>".
   // Returns false if serializing the message failed.
   template <typename T>
-  bool PackFrom(const T& message, StringPiece type_url_prefix) {
-    return InternalPackFrom(message, type_url_prefix, T::FullMessageName());
+  bool PackFrom(Arena* arena, const T& message, StringPiece type_url_prefix) {
+    return InternalPackFrom(arena, message, type_url_prefix, T::FullMessageName());
   }
 
-  bool PackFrom(const Message& message, StringPiece type_url_prefix);
+  bool PackFrom(Arena* arena, const Message& message, StringPiece type_url_prefix);
 
   // Unpacks the payload into the given message. Returns false if the message's
   // type doesn't match the type specified in the type URL (i.e., the full
@@ -108,7 +108,8 @@
   }
 
  private:
-  bool InternalPackFrom(const MessageLite& message,
+  bool InternalPackFrom(Arena* arena,
+                        const MessageLite& message,
                         StringPiece type_url_prefix,
                         StringPiece type_name);
   bool InternalUnpackTo(StringPiece type_name,
diff --git a/src/google/protobuf/any.pb.cc b/src/google/protobuf/any.pb.cc
index aaf6c1c..7fc1219 100644
--- a/src/google/protobuf/any.pb.cc
+++ b/src/google/protobuf/any.pb.cc
@@ -124,7 +124,7 @@
   // @@protoc_insertion_point(copy_constructor:google.protobuf.Any)
 }
 
-inline void Any::SharedCtor() {
+void Any::SharedCtor() {
 type_url_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
 value_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
 }
diff --git a/src/google/protobuf/any.pb.h b/src/google/protobuf/any.pb.h
index 36d57ee..f727663 100644
--- a/src/google/protobuf/any.pb.h
+++ b/src/google/protobuf/any.pb.h
@@ -8,12 +8,12 @@
 #include <string>
 
 #include <google/protobuf/port_def.inc>
-#if PROTOBUF_VERSION < 3015000
+#if PROTOBUF_VERSION < 3017000
 #error This file was generated by a newer version of protoc which is
 #error incompatible with your Protocol Buffer headers. Please update
 #error your headers.
 #endif
-#if 3015008 < PROTOBUF_MIN_PROTOC_VERSION
+#if 3017003 < 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.
@@ -52,7 +52,7 @@
   static const ::PROTOBUF_NAMESPACE_ID::internal::SerializationTable serialization_table[];
   static const ::PROTOBUF_NAMESPACE_ID::uint32 offsets[];
 };
-extern PROTOBUF_EXPORT const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable descriptor_table_google_2fprotobuf_2fany_2eproto;
+PROTOBUF_EXPORT extern const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable descriptor_table_google_2fprotobuf_2fany_2eproto;
 PROTOBUF_NAMESPACE_OPEN
 class Any;
 struct AnyDefaultTypeInternal;
@@ -114,11 +114,11 @@
   // implements Any -----------------------------------------------
 
   bool PackFrom(const ::PROTOBUF_NAMESPACE_ID::Message& message) {
-    return _any_metadata_.PackFrom(message);
+    return _any_metadata_.PackFrom(GetArena(), message);
   }
   bool PackFrom(const ::PROTOBUF_NAMESPACE_ID::Message& message,
                 ::PROTOBUF_NAMESPACE_ID::ConstStringParam type_url_prefix) {
-    return _any_metadata_.PackFrom(message, type_url_prefix);
+    return _any_metadata_.PackFrom(GetArena(), message, type_url_prefix);
   }
   bool UnpackTo(::PROTOBUF_NAMESPACE_ID::Message* message) const {
     return _any_metadata_.UnpackTo(message);
@@ -129,12 +129,12 @@
       const ::PROTOBUF_NAMESPACE_ID::FieldDescriptor** value_field);
   template <typename T, class = typename std::enable_if<!std::is_convertible<T, const ::PROTOBUF_NAMESPACE_ID::Message&>::value>::type>
   bool PackFrom(const T& message) {
-    return _any_metadata_.PackFrom<T>(message);
+    return _any_metadata_.PackFrom<T>(GetArena(), message);
   }
   template <typename T, class = typename std::enable_if<!std::is_convertible<T, const ::PROTOBUF_NAMESPACE_ID::Message&>::value>::type>
   bool PackFrom(const T& message,
                 ::PROTOBUF_NAMESPACE_ID::ConstStringParam type_url_prefix) {
-    return _any_metadata_.PackFrom<T>(message, type_url_prefix);}
+    return _any_metadata_.PackFrom<T>(GetArena(), message, type_url_prefix);}
   template <typename T, class = typename std::enable_if<!std::is_convertible<T, const ::PROTOBUF_NAMESPACE_ID::Message&>::value>::type>
   bool UnpackTo(T* message) const {
     return _any_metadata_.UnpackTo<T>(message);
diff --git a/src/google/protobuf/any_lite.cc b/src/google/protobuf/any_lite.cc
index 48e0fac..1fa06c7 100644
--- a/src/google/protobuf/any_lite.cc
+++ b/src/google/protobuf/any_lite.cc
@@ -53,13 +53,14 @@
 const char kTypeGoogleApisComPrefix[] = "type.googleapis.com/";
 const char kTypeGoogleProdComPrefix[] = "type.googleprod.com/";
 
-bool AnyMetadata::InternalPackFrom(const MessageLite& message,
+bool AnyMetadata::InternalPackFrom(Arena* arena,
+                                   const MessageLite& message,
                                    StringPiece type_url_prefix,
                                    StringPiece type_name) {
   type_url_->Set(&::google::protobuf::internal::GetEmptyString(),
-                 GetTypeUrl(type_name, type_url_prefix), nullptr);
+                 GetTypeUrl(type_name, type_url_prefix), arena);
   return message.SerializeToString(
-      value_->Mutable(ArenaStringPtr::EmptyDefault{}, nullptr));
+      value_->Mutable(ArenaStringPtr::EmptyDefault{}, arena));
 }
 
 bool AnyMetadata::InternalUnpackTo(StringPiece type_name,
diff --git a/src/google/protobuf/api.pb.cc b/src/google/protobuf/api.pb.cc
index 4aeabb1..8d45b60 100644
--- a/src/google/protobuf/api.pb.cc
+++ b/src/google/protobuf/api.pb.cc
@@ -218,7 +218,7 @@
   // @@protoc_insertion_point(copy_constructor:google.protobuf.Api)
 }
 
-inline void Api::SharedCtor() {
+void Api::SharedCtor() {
 name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
 version_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
 ::memset(reinterpret_cast<char*>(this) + static_cast<size_t>(
@@ -631,7 +631,7 @@
   // @@protoc_insertion_point(copy_constructor:google.protobuf.Method)
 }
 
-inline void Method::SharedCtor() {
+void Method::SharedCtor() {
 name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
 request_type_url_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
 response_type_url_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
@@ -1022,7 +1022,7 @@
   // @@protoc_insertion_point(copy_constructor:google.protobuf.Mixin)
 }
 
-inline void Mixin::SharedCtor() {
+void Mixin::SharedCtor() {
 name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
 root_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
 }
diff --git a/src/google/protobuf/api.pb.h b/src/google/protobuf/api.pb.h
index 1a3376e..1708da8 100644
--- a/src/google/protobuf/api.pb.h
+++ b/src/google/protobuf/api.pb.h
@@ -8,12 +8,12 @@
 #include <string>
 
 #include <google/protobuf/port_def.inc>
-#if PROTOBUF_VERSION < 3015000
+#if PROTOBUF_VERSION < 3017000
 #error This file was generated by a newer version of protoc which is
 #error incompatible with your Protocol Buffer headers. Please update
 #error your headers.
 #endif
-#if 3015008 < PROTOBUF_MIN_PROTOC_VERSION
+#if 3017003 < 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.
@@ -54,7 +54,7 @@
   static const ::PROTOBUF_NAMESPACE_ID::internal::SerializationTable serialization_table[];
   static const ::PROTOBUF_NAMESPACE_ID::uint32 offsets[];
 };
-extern PROTOBUF_EXPORT const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable descriptor_table_google_2fprotobuf_2fapi_2eproto;
+PROTOBUF_EXPORT extern const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable descriptor_table_google_2fprotobuf_2fapi_2eproto;
 PROTOBUF_NAMESPACE_OPEN
 class Api;
 struct ApiDefaultTypeInternal;
diff --git a/src/google/protobuf/arena.h b/src/google/protobuf/arena.h
index f454b84..305a511 100644
--- a/src/google/protobuf/arena.h
+++ b/src/google/protobuf/arena.h
@@ -443,7 +443,7 @@
     }
 
     static Arena* GetArenaForAllocationForNonMessageNonArenaConstructible(
-        const T* p, std::false_type /*has_get_arena*/) {
+        const T* /* p */, std::false_type /*has_get_arena*/) {
       return nullptr;
     }
 
@@ -750,7 +750,7 @@
   }
   template <typename T>
   PROTOBUF_ALWAYS_INLINE static Arena* GetOwningArenaInternal(
-      const T* value, std::false_type) {
+      const T* /* value */, std::false_type) {
     return nullptr;
   }
 
diff --git a/src/google/protobuf/compiler/command_line_interface.cc b/src/google/protobuf/compiler/command_line_interface.cc
index 57e81f8..a68a604 100644
--- a/src/google/protobuf/compiler/command_line_interface.cc
+++ b/src/google/protobuf/compiler/command_line_interface.cc
@@ -298,36 +298,36 @@
 
   // implements MultiFileErrorCollector ------------------------------
   void AddError(const std::string& filename, int line, int column,
-                const std::string& message) {
+                const std::string& message) override {
     found_errors_ = true;
     AddErrorOrWarning(filename, line, column, message, "error", std::cerr);
   }
 
   void AddWarning(const std::string& filename, int line, int column,
-                  const std::string& message) {
+                  const std::string& message) override {
     found_warnings_ = true;
     AddErrorOrWarning(filename, line, column, message, "warning", std::clog);
   }
 
   // implements io::ErrorCollector -----------------------------------
-  void AddError(int line, int column, const std::string& message) {
+  void AddError(int line, int column, const std::string& message) override {
     AddError("input", line, column, message);
   }
 
-  void AddWarning(int line, int column, const std::string& message) {
+  void AddWarning(int line, int column, const std::string& message) override {
     AddErrorOrWarning("input", line, column, message, "warning", std::clog);
   }
 
   // implements DescriptorPool::ErrorCollector-------------------------
   void AddError(const std::string& filename, const std::string& element_name,
                 const Message* descriptor, ErrorLocation location,
-                const std::string& message) {
+                const std::string& message) override {
     AddErrorOrWarning(filename, -1, -1, message, "error", std::cerr);
   }
 
   void AddWarning(const std::string& filename, const std::string& element_name,
                   const Message* descriptor, ErrorLocation location,
-                  const std::string& message) {
+                  const std::string& message) override {
     AddErrorOrWarning(filename, -1, -1, message, "warning", std::clog);
   }
 
@@ -400,14 +400,14 @@
   void GetOutputFilenames(std::vector<std::string>* output_filenames);
 
   // implements GeneratorContext --------------------------------------
-  io::ZeroCopyOutputStream* Open(const std::string& filename);
-  io::ZeroCopyOutputStream* OpenForAppend(const std::string& filename);
+  io::ZeroCopyOutputStream* Open(const std::string& filename) override;
+  io::ZeroCopyOutputStream* OpenForAppend(const std::string& filename) override;
   io::ZeroCopyOutputStream* OpenForInsert(const std::string& filename,
-                                          const std::string& insertion_point);
+                                          const std::string& insertion_point) override;
   io::ZeroCopyOutputStream* OpenForInsertWithGeneratedCodeInfo(
       const std::string& filename, const std::string& insertion_point,
-      const google::protobuf::GeneratedCodeInfo& info);
-  void ListParsedFiles(std::vector<const FileDescriptor*>* output) {
+      const google::protobuf::GeneratedCodeInfo& info) override;
+  void ListParsedFiles(std::vector<const FileDescriptor*>* output) override {
     *output = parsed_files_;
   }
 
diff --git a/src/google/protobuf/compiler/cpp/cpp_enum_field.cc b/src/google/protobuf/compiler/cpp/cpp_enum_field.cc
index 6b9a5eb..cdcd9a6 100644
--- a/src/google/protobuf/compiler/cpp/cpp_enum_field.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_enum_field.cc
@@ -496,7 +496,7 @@
   format("$name$_()");
   if (descriptor_->is_packed() &&
       HasGeneratedMethods(descriptor_->file(), options_)) {
-    format("\n, _$name$_cached_byte_size_()");
+    format("\n, _$name$_cached_byte_size_(0)");
   }
 }
 
diff --git a/src/google/protobuf/compiler/cpp/cpp_enum_field.h b/src/google/protobuf/compiler/cpp/cpp_enum_field.h
index 3fa64a8..793ab2d 100644
--- a/src/google/protobuf/compiler/cpp/cpp_enum_field.h
+++ b/src/google/protobuf/compiler/cpp/cpp_enum_field.h
@@ -50,17 +50,18 @@
   ~EnumFieldGenerator();
 
   // implements FieldGenerator ---------------------------------------
-  void GeneratePrivateMembers(io::Printer* printer) const;
-  void GenerateAccessorDeclarations(io::Printer* printer) const;
-  void GenerateInlineAccessorDefinitions(io::Printer* printer) const;
-  void GenerateClearingCode(io::Printer* printer) const;
-  void GenerateMergingCode(io::Printer* printer) const;
-  void GenerateSwappingCode(io::Printer* printer) const;
-  void GenerateConstructorCode(io::Printer* printer) const;
-  void GenerateCopyConstructorCode(io::Printer* printer) const;
-  void GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const;
-  void GenerateByteSize(io::Printer* printer) const;
-  void GenerateConstinitInitializer(io::Printer* printer) const;
+  void GeneratePrivateMembers(io::Printer* printer) const override;
+  void GenerateAccessorDeclarations(io::Printer* printer) const override;
+  void GenerateInlineAccessorDefinitions(io::Printer* printer) const override;
+  void GenerateClearingCode(io::Printer* printer) const override;
+  void GenerateMergingCode(io::Printer* printer) const override;
+  void GenerateSwappingCode(io::Printer* printer) const override;
+  void GenerateConstructorCode(io::Printer* printer) const override;
+  void GenerateCopyConstructorCode(io::Printer* printer) const override;
+  void GenerateSerializeWithCachedSizesToArray(
+      io::Printer* printer) const override;
+  void GenerateByteSize(io::Printer* printer) const override;
+  void GenerateConstinitInitializer(io::Printer* printer) const override;
 
  private:
   GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(EnumFieldGenerator);
@@ -73,10 +74,10 @@
   ~EnumOneofFieldGenerator();
 
   // implements FieldGenerator ---------------------------------------
-  void GenerateInlineAccessorDefinitions(io::Printer* printer) const;
-  void GenerateClearingCode(io::Printer* printer) const;
-  void GenerateSwappingCode(io::Printer* printer) const;
-  void GenerateConstructorCode(io::Printer* printer) const;
+  void GenerateInlineAccessorDefinitions(io::Printer* printer) const override;
+  void GenerateClearingCode(io::Printer* printer) const override;
+  void GenerateSwappingCode(io::Printer* printer) const override;
+  void GenerateConstructorCode(io::Printer* printer) const override;
 
  private:
   GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(EnumOneofFieldGenerator);
@@ -89,19 +90,20 @@
   ~RepeatedEnumFieldGenerator();
 
   // implements FieldGenerator ---------------------------------------
-  void GeneratePrivateMembers(io::Printer* printer) const;
-  void GenerateAccessorDeclarations(io::Printer* printer) const;
-  void GenerateInlineAccessorDefinitions(io::Printer* printer) const;
-  void GenerateClearingCode(io::Printer* printer) const;
-  void GenerateMergingCode(io::Printer* printer) const;
-  void GenerateSwappingCode(io::Printer* printer) const;
-  void GenerateConstructorCode(io::Printer* printer) const;
-  void GenerateCopyConstructorCode(io::Printer* printer) const {}
+  void GeneratePrivateMembers(io::Printer* printer) const override;
+  void GenerateAccessorDeclarations(io::Printer* printer) const override;
+  void GenerateInlineAccessorDefinitions(io::Printer* printer) const override;
+  void GenerateClearingCode(io::Printer* printer) const override;
+  void GenerateMergingCode(io::Printer* printer) const override;
+  void GenerateSwappingCode(io::Printer* printer) const override;
+  void GenerateConstructorCode(io::Printer* printer) const override;
+  void GenerateCopyConstructorCode(io::Printer* printer) const override {}
   void GenerateMergeFromCodedStream(io::Printer* printer) const;
   void GenerateMergeFromCodedStreamWithPacking(io::Printer* printer) const;
-  void GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const;
-  void GenerateByteSize(io::Printer* printer) const;
-  void GenerateConstinitInitializer(io::Printer* printer) const;
+  void GenerateSerializeWithCachedSizesToArray(
+      io::Printer* printer) const override;
+  void GenerateByteSize(io::Printer* printer) const override;
+  void GenerateConstinitInitializer(io::Printer* printer) const override;
 
  private:
   GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedEnumFieldGenerator);
diff --git a/src/google/protobuf/compiler/cpp/cpp_file.cc b/src/google/protobuf/compiler/cpp/cpp_file.cc
index 8045b05..1f20c4d 100644
--- a/src/google/protobuf/compiler/cpp/cpp_file.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_file.cc
@@ -1309,7 +1309,7 @@
       std::max(size_t(1), message_generators_.size()));
   if (HasDescriptorMethods(file_, options_)) {
     format(
-        "extern $dllexport_decl $const ::$proto_ns$::internal::DescriptorTable "
+        "$dllexport_decl $extern const ::$proto_ns$::internal::DescriptorTable "
         "$desc_table$;\n");
   }
 }
diff --git a/src/google/protobuf/compiler/cpp/cpp_helpers.cc b/src/google/protobuf/compiler/cpp/cpp_helpers.cc
index 001586a..25206db 100644
--- a/src/google/protobuf/compiler/cpp/cpp_helpers.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_helpers.cc
@@ -169,30 +169,6 @@
 
 static std::unordered_set<std::string>& kKeywords = *MakeKeywordsMap();
 
-// Encode [0..63] as 'A'-'Z', 'a'-'z', '0'-'9', '_'
-char Base63Char(int value) {
-  GOOGLE_CHECK_GE(value, 0);
-  if (value < 26) return 'A' + value;
-  value -= 26;
-  if (value < 26) return 'a' + value;
-  value -= 26;
-  if (value < 10) return '0' + value;
-  GOOGLE_CHECK_EQ(value, 10);
-  return '_';
-}
-
-// Given a c identifier has 63 legal characters we can't implement base64
-// encoding. So we return the k least significant "digits" in base 63.
-template <typename I>
-std::string Base63(I n, int k) {
-  std::string res;
-  while (k-- > 0) {
-    res += Base63Char(static_cast<int>(n % 63));
-    n /= 63;
-  }
-  return res;
-}
-
 std::string IntTypeName(const Options& options, const std::string& type) {
   if (options.opensource_runtime) {
     return "::PROTOBUF_NAMESPACE_ID::" + type;
diff --git a/src/google/protobuf/compiler/cpp/cpp_helpers.h b/src/google/protobuf/compiler/cpp/cpp_helpers.h
index 37bfb9e..88befc0 100644
--- a/src/google/protobuf/compiler/cpp/cpp_helpers.h
+++ b/src/google/protobuf/compiler/cpp/cpp_helpers.h
@@ -363,7 +363,7 @@
 }
 
 inline bool IsFieldUsed(const FieldDescriptor* /* field */,
-                        const Options& options) {
+                        const Options& /* options */) {
   return true;
 }
 
diff --git a/src/google/protobuf/compiler/cpp/cpp_message.cc b/src/google/protobuf/compiler/cpp/cpp_message.cc
index 3955168..d15f9b6 100644
--- a/src/google/protobuf/compiler/cpp/cpp_message.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_message.cc
@@ -1472,7 +1472,7 @@
   if (options_.table_driven_serialization) {
     format(
         "private:\n"
-        "const void* InternalGetTable() const;\n"
+        "const void* InternalGetTable() const override;\n"
         "public:\n"
         "\n");
   }
@@ -1556,12 +1556,12 @@
     if (HasDescriptorMethods(descriptor_->file(), options_)) {
       format(
           "bool PackFrom(const ::$proto_ns$::Message& message) {\n"
-          "  return _any_metadata_.PackFrom(message);\n"
+          "  return _any_metadata_.PackFrom(GetArena(), message);\n"
           "}\n"
           "bool PackFrom(const ::$proto_ns$::Message& message,\n"
           "              ::PROTOBUF_NAMESPACE_ID::ConstStringParam "
           "type_url_prefix) {\n"
-          "  return _any_metadata_.PackFrom(message, type_url_prefix);\n"
+          "  return _any_metadata_.PackFrom(GetArena(), message, type_url_prefix);\n"
           "}\n"
           "bool UnpackTo(::$proto_ns$::Message* message) const {\n"
           "  return _any_metadata_.UnpackTo(message);\n"
@@ -1574,7 +1574,7 @@
           "!std::is_convertible<T, const ::$proto_ns$::Message&>"
           "::value>::type>\n"
           "bool PackFrom(const T& message) {\n"
-          "  return _any_metadata_.PackFrom<T>(message);\n"
+          "  return _any_metadata_.PackFrom<T>(GetArena(), message);\n"
           "}\n"
           "template <typename T, class = typename std::enable_if<"
           "!std::is_convertible<T, const ::$proto_ns$::Message&>"
@@ -1582,7 +1582,7 @@
           "bool PackFrom(const T& message,\n"
           "              ::PROTOBUF_NAMESPACE_ID::ConstStringParam "
           "type_url_prefix) {\n"
-          "  return _any_metadata_.PackFrom<T>(message, type_url_prefix);"
+          "  return _any_metadata_.PackFrom<T>(GetArena(), message, type_url_prefix);"
           "}\n"
           "template <typename T, class = typename std::enable_if<"
           "!std::is_convertible<T, const ::$proto_ns$::Message&>"
@@ -2792,7 +2792,7 @@
   if (HasSimpleBaseClass(descriptor_, options_)) return;
   Formatter format(printer, variables_);
 
-  format("inline void $classname$::SharedCtor() {\n");
+  format("void $classname$::SharedCtor() {\n");
 
   std::vector<bool> processed(optimized_order_.size(), false);
   GenerateConstructorBody(printer, processed, false);
diff --git a/src/google/protobuf/compiler/cpp/cpp_message_field.h b/src/google/protobuf/compiler/cpp/cpp_message_field.h
index 4b4b8ea..712ddbf 100644
--- a/src/google/protobuf/compiler/cpp/cpp_message_field.h
+++ b/src/google/protobuf/compiler/cpp/cpp_message_field.h
@@ -53,22 +53,25 @@
   ~MessageFieldGenerator();
 
   // implements FieldGenerator ---------------------------------------
-  void GeneratePrivateMembers(io::Printer* printer) const;
-  void GenerateAccessorDeclarations(io::Printer* printer) const;
-  void GenerateInlineAccessorDefinitions(io::Printer* printer) const;
-  void GenerateNonInlineAccessorDefinitions(io::Printer* printer) const;
-  void GenerateInternalAccessorDeclarations(io::Printer* printer) const;
-  void GenerateInternalAccessorDefinitions(io::Printer* printer) const;
-  void GenerateClearingCode(io::Printer* printer) const;
-  void GenerateMessageClearingCode(io::Printer* printer) const;
-  void GenerateMergingCode(io::Printer* printer) const;
-  void GenerateSwappingCode(io::Printer* printer) const;
-  void GenerateDestructorCode(io::Printer* printer) const;
-  void GenerateConstructorCode(io::Printer* printer) const;
-  void GenerateCopyConstructorCode(io::Printer* printer) const;
-  void GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const;
-  void GenerateByteSize(io::Printer* printer) const;
-  void GenerateConstinitInitializer(io::Printer* printer) const;
+  void GeneratePrivateMembers(io::Printer* printer) const override;
+  void GenerateAccessorDeclarations(io::Printer* printer) const override;
+  void GenerateInlineAccessorDefinitions(io::Printer* printer) const override;
+  void GenerateNonInlineAccessorDefinitions(
+      io::Printer* printer) const override;
+  void GenerateInternalAccessorDeclarations(
+      io::Printer* printer) const override;
+  void GenerateInternalAccessorDefinitions(io::Printer* printer) const override;
+  void GenerateClearingCode(io::Printer* printer) const override;
+  void GenerateMessageClearingCode(io::Printer* printer) const override;
+  void GenerateMergingCode(io::Printer* printer) const override;
+  void GenerateSwappingCode(io::Printer* printer) const override;
+  void GenerateDestructorCode(io::Printer* printer) const override;
+  void GenerateConstructorCode(io::Printer* printer) const override;
+  void GenerateCopyConstructorCode(io::Printer* printer) const override;
+  void GenerateSerializeWithCachedSizesToArray(
+      io::Printer* printer) const override;
+  void GenerateByteSize(io::Printer* printer) const override;
+  void GenerateConstinitInitializer(io::Printer* printer) const override;
 
  protected:
   const bool implicit_weak_field_;
@@ -85,16 +88,17 @@
   ~MessageOneofFieldGenerator();
 
   // implements FieldGenerator ---------------------------------------
-  void GenerateInlineAccessorDefinitions(io::Printer* printer) const;
-  void GenerateNonInlineAccessorDefinitions(io::Printer* printer) const;
-  void GenerateClearingCode(io::Printer* printer) const;
+  void GenerateInlineAccessorDefinitions(io::Printer* printer) const override;
+  void GenerateNonInlineAccessorDefinitions(
+      io::Printer* printer) const override;
+  void GenerateClearingCode(io::Printer* printer) const override;
 
   // MessageFieldGenerator, from which we inherit, overrides this so we need to
   // override it as well.
-  void GenerateMessageClearingCode(io::Printer* printer) const;
-  void GenerateSwappingCode(io::Printer* printer) const;
-  void GenerateDestructorCode(io::Printer* printer) const;
-  void GenerateConstructorCode(io::Printer* printer) const;
+  void GenerateMessageClearingCode(io::Printer* printer) const override;
+  void GenerateSwappingCode(io::Printer* printer) const override;
+  void GenerateDestructorCode(io::Printer* printer) const override;
+  void GenerateConstructorCode(io::Printer* printer) const override;
 
  private:
   GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MessageOneofFieldGenerator);
@@ -108,17 +112,18 @@
   ~RepeatedMessageFieldGenerator();
 
   // implements FieldGenerator ---------------------------------------
-  void GeneratePrivateMembers(io::Printer* printer) const;
-  void GenerateAccessorDeclarations(io::Printer* printer) const;
-  void GenerateInlineAccessorDefinitions(io::Printer* printer) const;
-  void GenerateClearingCode(io::Printer* printer) const;
-  void GenerateMergingCode(io::Printer* printer) const;
-  void GenerateSwappingCode(io::Printer* printer) const;
-  void GenerateConstructorCode(io::Printer* printer) const;
-  void GenerateCopyConstructorCode(io::Printer* printer) const {}
-  void GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const;
-  void GenerateByteSize(io::Printer* printer) const;
-  void GenerateConstinitInitializer(io::Printer* printer) const;
+  void GeneratePrivateMembers(io::Printer* printer) const override;
+  void GenerateAccessorDeclarations(io::Printer* printer) const override;
+  void GenerateInlineAccessorDefinitions(io::Printer* printer) const override;
+  void GenerateClearingCode(io::Printer* printer) const override;
+  void GenerateMergingCode(io::Printer* printer) const override;
+  void GenerateSwappingCode(io::Printer* printer) const override;
+  void GenerateConstructorCode(io::Printer* printer) const override;
+  void GenerateCopyConstructorCode(io::Printer* printer) const override {}
+  void GenerateSerializeWithCachedSizesToArray(
+      io::Printer* printer) const override;
+  void GenerateByteSize(io::Printer* printer) const override;
+  void GenerateConstinitInitializer(io::Printer* printer) const override;
 
  private:
   const bool implicit_weak_field_;
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 c1f9e46..3991d12 100644
--- a/src/google/protobuf/compiler/cpp/cpp_parse_function_generator.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_parse_function_generator.cc
@@ -1143,6 +1143,11 @@
         case Utf8CheckMode::kVerify:
           type_format = TypeFormat::kStringValidateOnly;
           break;
+        default:
+          GOOGLE_LOG(DFATAL)
+              << "Mode not handled: "
+              << static_cast<int>(GetUtf8CheckMode(field, options));
+          return "";
       }
       break;
 
diff --git a/src/google/protobuf/compiler/cpp/cpp_primitive_field.cc b/src/google/protobuf/compiler/cpp/cpp_primitive_field.cc
index 76862d4..ffccf08 100644
--- a/src/google/protobuf/compiler/cpp/cpp_primitive_field.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_primitive_field.cc
@@ -495,7 +495,7 @@
   format("$name$_()");
   if (descriptor_->is_packed() && FixedSize(descriptor_->type()) == -1 &&
       HasGeneratedMethods(descriptor_->file(), options_)) {
-    format("\n, _$name$_cached_byte_size_()");
+    format("\n, _$name$_cached_byte_size_(0)");
   }
 }
 
diff --git a/src/google/protobuf/compiler/cpp/cpp_primitive_field.h b/src/google/protobuf/compiler/cpp/cpp_primitive_field.h
index 394b304..ce0f97d 100644
--- a/src/google/protobuf/compiler/cpp/cpp_primitive_field.h
+++ b/src/google/protobuf/compiler/cpp/cpp_primitive_field.h
@@ -51,17 +51,17 @@
   ~PrimitiveFieldGenerator();
 
   // implements FieldGenerator ---------------------------------------
-  void GeneratePrivateMembers(io::Printer* printer) const;
-  void GenerateAccessorDeclarations(io::Printer* printer) const;
-  void GenerateInlineAccessorDefinitions(io::Printer* printer) const;
-  void GenerateClearingCode(io::Printer* printer) const;
-  void GenerateMergingCode(io::Printer* printer) const;
-  void GenerateSwappingCode(io::Printer* printer) const;
-  void GenerateConstructorCode(io::Printer* printer) const;
-  void GenerateCopyConstructorCode(io::Printer* printer) const;
-  void GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const;
-  void GenerateByteSize(io::Printer* printer) const;
-  void GenerateConstinitInitializer(io::Printer* printer) const;
+  void GeneratePrivateMembers(io::Printer* printer) const override;
+  void GenerateAccessorDeclarations(io::Printer* printer) const override;
+  void GenerateInlineAccessorDefinitions(io::Printer* printer) const override;
+  void GenerateClearingCode(io::Printer* printer) const override;
+  void GenerateMergingCode(io::Printer* printer) const override;
+  void GenerateSwappingCode(io::Printer* printer) const override;
+  void GenerateConstructorCode(io::Printer* printer) const override;
+  void GenerateCopyConstructorCode(io::Printer* printer) const override;
+  void GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const override;
+  void GenerateByteSize(io::Printer* printer) const override;
+  void GenerateConstinitInitializer(io::Printer* printer) const override;
 
  private:
   GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(PrimitiveFieldGenerator);
@@ -74,10 +74,10 @@
   ~PrimitiveOneofFieldGenerator();
 
   // implements FieldGenerator ---------------------------------------
-  void GenerateInlineAccessorDefinitions(io::Printer* printer) const;
-  void GenerateClearingCode(io::Printer* printer) const;
-  void GenerateSwappingCode(io::Printer* printer) const;
-  void GenerateConstructorCode(io::Printer* printer) const;
+  void GenerateInlineAccessorDefinitions(io::Printer* printer) const override;
+  void GenerateClearingCode(io::Printer* printer) const override;
+  void GenerateSwappingCode(io::Printer* printer) const override;
+  void GenerateConstructorCode(io::Printer* printer) const override;
 
  private:
   GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(PrimitiveOneofFieldGenerator);
@@ -90,17 +90,17 @@
   ~RepeatedPrimitiveFieldGenerator();
 
   // implements FieldGenerator ---------------------------------------
-  void GeneratePrivateMembers(io::Printer* printer) const;
-  void GenerateAccessorDeclarations(io::Printer* printer) const;
-  void GenerateInlineAccessorDefinitions(io::Printer* printer) const;
-  void GenerateClearingCode(io::Printer* printer) const;
-  void GenerateMergingCode(io::Printer* printer) const;
-  void GenerateSwappingCode(io::Printer* printer) const;
-  void GenerateConstructorCode(io::Printer* printer) const;
-  void GenerateCopyConstructorCode(io::Printer* printer) const;
-  void GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const;
-  void GenerateByteSize(io::Printer* printer) const;
-  void GenerateConstinitInitializer(io::Printer* printer) const;
+  void GeneratePrivateMembers(io::Printer* printer) const override;
+  void GenerateAccessorDeclarations(io::Printer* printer) const override;
+  void GenerateInlineAccessorDefinitions(io::Printer* printer) const override;
+  void GenerateClearingCode(io::Printer* printer) const override;
+  void GenerateMergingCode(io::Printer* printer) const override;
+  void GenerateSwappingCode(io::Printer* printer) const override;
+  void GenerateConstructorCode(io::Printer* printer) const override;
+  void GenerateCopyConstructorCode(io::Printer* printer) const override;
+  void GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const override;
+  void GenerateByteSize(io::Printer* printer) const override;
+  void GenerateConstinitInitializer(io::Printer* printer) const override;
 
  private:
   GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedPrimitiveFieldGenerator);
diff --git a/src/google/protobuf/compiler/cpp/cpp_string_field.h b/src/google/protobuf/compiler/cpp/cpp_string_field.h
index 92d5350..85689bb 100644
--- a/src/google/protobuf/compiler/cpp/cpp_string_field.h
+++ b/src/google/protobuf/compiler/cpp/cpp_string_field.h
@@ -51,21 +51,21 @@
   ~StringFieldGenerator();
 
   // implements FieldGenerator ---------------------------------------
-  void GeneratePrivateMembers(io::Printer* printer) const;
-  void GenerateStaticMembers(io::Printer* printer) const;
-  void GenerateAccessorDeclarations(io::Printer* printer) const;
-  void GenerateInlineAccessorDefinitions(io::Printer* printer) const;
-  void GenerateNonInlineAccessorDefinitions(io::Printer* printer) const;
-  void GenerateClearingCode(io::Printer* printer) const;
-  void GenerateMessageClearingCode(io::Printer* printer) const;
-  void GenerateMergingCode(io::Printer* printer) const;
-  void GenerateSwappingCode(io::Printer* printer) const;
-  void GenerateConstructorCode(io::Printer* printer) const;
-  void GenerateCopyConstructorCode(io::Printer* printer) const;
-  void GenerateDestructorCode(io::Printer* printer) const;
-  void GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const;
-  void GenerateByteSize(io::Printer* printer) const;
-  void GenerateConstinitInitializer(io::Printer* printer) const;
+  void GeneratePrivateMembers(io::Printer* printer) const override;
+  void GenerateStaticMembers(io::Printer* printer) const override;
+  void GenerateAccessorDeclarations(io::Printer* printer) const override;
+  void GenerateInlineAccessorDefinitions(io::Printer* printer) const override;
+  void GenerateNonInlineAccessorDefinitions(io::Printer* printer) const override;
+  void GenerateClearingCode(io::Printer* printer) const override;
+  void GenerateMessageClearingCode(io::Printer* printer) const override;
+  void GenerateMergingCode(io::Printer* printer) const override;
+  void GenerateSwappingCode(io::Printer* printer) const override;
+  void GenerateConstructorCode(io::Printer* printer) const override;
+  void GenerateCopyConstructorCode(io::Printer* printer) const override;
+  void GenerateDestructorCode(io::Printer* printer) const override;
+  void GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const override;
+  void GenerateByteSize(io::Printer* printer) const override;
+  void GenerateConstinitInitializer(io::Printer* printer) const override;
   bool IsInlined() const override { return inlined_; }
 
  private:
@@ -80,14 +80,14 @@
   ~StringOneofFieldGenerator();
 
   // implements FieldGenerator ---------------------------------------
-  void GenerateInlineAccessorDefinitions(io::Printer* printer) const;
-  void GenerateClearingCode(io::Printer* printer) const;
+  void GenerateInlineAccessorDefinitions(io::Printer* printer) const override;
+  void GenerateClearingCode(io::Printer* printer) const override;
 
   // StringFieldGenerator, from which we inherit, overrides this so we need to
   // override it as well.
-  void GenerateMessageClearingCode(io::Printer* printer) const;
-  void GenerateSwappingCode(io::Printer* printer) const;
-  void GenerateConstructorCode(io::Printer* printer) const;
+  void GenerateMessageClearingCode(io::Printer* printer) const override;
+  void GenerateSwappingCode(io::Printer* printer) const override;
+  void GenerateConstructorCode(io::Printer* printer) const override;
 
  private:
   GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(StringOneofFieldGenerator);
@@ -100,17 +100,17 @@
   ~RepeatedStringFieldGenerator();
 
   // implements FieldGenerator ---------------------------------------
-  void GeneratePrivateMembers(io::Printer* printer) const;
-  void GenerateAccessorDeclarations(io::Printer* printer) const;
-  void GenerateInlineAccessorDefinitions(io::Printer* printer) const;
-  void GenerateClearingCode(io::Printer* printer) const;
-  void GenerateMergingCode(io::Printer* printer) const;
-  void GenerateSwappingCode(io::Printer* printer) const;
-  void GenerateConstructorCode(io::Printer* printer) const;
-  void GenerateCopyConstructorCode(io::Printer* printer) const;
-  void GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const;
-  void GenerateByteSize(io::Printer* printer) const;
-  void GenerateConstinitInitializer(io::Printer* printer) const;
+  void GeneratePrivateMembers(io::Printer* printer) const override;
+  void GenerateAccessorDeclarations(io::Printer* printer) const override;
+  void GenerateInlineAccessorDefinitions(io::Printer* printer) const override;
+  void GenerateClearingCode(io::Printer* printer) const override;
+  void GenerateMergingCode(io::Printer* printer) const override;
+  void GenerateSwappingCode(io::Printer* printer) const override;
+  void GenerateConstructorCode(io::Printer* printer) const override;
+  void GenerateCopyConstructorCode(io::Printer* printer) const override;
+  void GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const override;
+  void GenerateByteSize(io::Printer* printer) const override;
+  void GenerateConstinitInitializer(io::Printer* printer) const override;
 
  private:
   GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedStringFieldGenerator);
diff --git a/src/google/protobuf/compiler/cpp/cpp_unittest.inc b/src/google/protobuf/compiler/cpp/cpp_unittest.inc
index 10e28a8..24104db 100644
--- a/src/google/protobuf/compiler/cpp/cpp_unittest.inc
+++ b/src/google/protobuf/compiler/cpp/cpp_unittest.inc
@@ -101,7 +101,7 @@
 
   // implements ErrorCollector ---------------------------------------
   void AddError(const std::string& filename, int line, int column,
-                const std::string& message) {
+                const std::string& message) override {
     strings::SubstituteAndAppend(&text_, "$0:$1:$2: $3\n", filename, line, column,
                               message);
   }
@@ -1157,7 +1157,7 @@
     void Foo(RpcController* controller,
              const UNITTEST::FooRequest* request,
              UNITTEST::FooResponse* response,
-             Closure* done) {
+             Closure* done) override {
       ASSERT_FALSE(called_);
       called_ = true;
       method_ = "Foo";
@@ -1170,7 +1170,7 @@
     void Bar(RpcController* controller,
              const UNITTEST::BarRequest* request,
              UNITTEST::BarResponse* response,
-             Closure* done) {
+             Closure* done) override {
       ASSERT_FALSE(called_);
       called_ = true;
       method_ = "Bar";
@@ -1213,7 +1213,7 @@
                     RpcController* controller,
                     const Message* request,
                     Message* response,
-                    Closure* done) {
+                    Closure* done) override {
       ASSERT_FALSE(called_);
       called_ = true;
       method_ = method;
@@ -1236,28 +1236,28 @@
 
   class MockController : public RpcController {
    public:
-    void Reset() {
+    void Reset() override {
       ADD_FAILURE() << "Reset() not expected during this test.";
     }
-    bool Failed() const {
+    bool Failed() const override {
       ADD_FAILURE() << "Failed() not expected during this test.";
       return false;
     }
-    std::string ErrorText() const {
+    std::string ErrorText() const override {
       ADD_FAILURE() << "ErrorText() not expected during this test.";
       return "";
     }
-    void StartCancel() {
+    void StartCancel() override {
       ADD_FAILURE() << "StartCancel() not expected during this test.";
     }
-    void SetFailed(const std::string& reason) {
+    void SetFailed(const std::string& reason) override {
       ADD_FAILURE() << "SetFailed() not expected during this test.";
     }
-    bool IsCanceled() const {
+    bool IsCanceled() const override {
       ADD_FAILURE() << "IsCanceled() not expected during this test.";
       return false;
     }
-    void NotifyOnCancel(Closure* callback) {
+    void NotifyOnCancel(Closure* callback) override {
       ADD_FAILURE() << "NotifyOnCancel() not expected during this test.";
     }
   };
@@ -1269,7 +1269,7 @@
       stub_(&mock_channel_),
       done_(::google::protobuf::NewPermanentCallback(&DoNothing)) {}
 
-  virtual void SetUp() {
+  virtual void SetUp() override {
     ASSERT_TRUE(foo_ != NULL);
     ASSERT_TRUE(bar_ != NULL);
   }
@@ -1410,7 +1410,7 @@
    public:
     ExpectUnimplementedController() : called_(false) {}
 
-    void SetFailed(const std::string& reason) {
+    void SetFailed(const std::string& reason) override {
       EXPECT_FALSE(called_);
       called_ = true;
       EXPECT_EQ("Method Foo() not implemented.", reason);
@@ -1432,7 +1432,7 @@
 
 class OneofTest : public testing::Test {
  protected:
-  virtual void SetUp() {
+  virtual void SetUp() override {
   }
 
   void ExpectEnumCasesWork(const UNITTEST::TestOneof2 &message) {
diff --git a/src/google/protobuf/compiler/importer.cc b/src/google/protobuf/compiler/importer.cc
index c629b2e..d0b3f4c 100644
--- a/src/google/protobuf/compiler/importer.cc
+++ b/src/google/protobuf/compiler/importer.cc
@@ -290,11 +290,11 @@
   std::vector<std::string> canonical_parts;
   std::vector<std::string> parts = Split(
       path, "/", true);  // Note:  Removes empty parts.
-  for (int i = 0; i < parts.size(); i++) {
-    if (parts[i] == ".") {
+  for (const std::string& part : parts) {
+    if (part == ".") {
       // Ignore.
     } else {
-      canonical_parts.push_back(parts[i]);
+      canonical_parts.push_back(part);
     }
   }
   std::string result = Join(canonical_parts, "/");
@@ -464,10 +464,10 @@
     return NULL;
   }
 
-  for (int i = 0; i < mappings_.size(); i++) {
+  for (const auto& mapping : mappings_) {
     std::string temp_disk_file;
-    if (ApplyMapping(virtual_file, mappings_[i].virtual_path,
-                     mappings_[i].disk_path, &temp_disk_file)) {
+    if (ApplyMapping(virtual_file, mapping.virtual_path, mapping.disk_path,
+          &temp_disk_file)) {
       io::ZeroCopyInputStream* stream = OpenDiskFile(temp_disk_file);
       if (stream != NULL) {
         if (disk_file != NULL) {
diff --git a/src/google/protobuf/compiler/java/java_enum_field.h b/src/google/protobuf/compiler/java/java_enum_field.h
index 5d4e2a7..82dbd9e 100644
--- a/src/google/protobuf/compiler/java/java_enum_field.h
+++ b/src/google/protobuf/compiler/java/java_enum_field.h
@@ -101,15 +101,15 @@
                                    Context* context);
   ~ImmutableEnumOneofFieldGenerator();
 
-  void GenerateMembers(io::Printer* printer) const;
-  void GenerateBuilderMembers(io::Printer* printer) const;
-  void GenerateMergingCode(io::Printer* printer) const;
-  void GenerateBuildingCode(io::Printer* printer) const;
-  void GenerateParsingCode(io::Printer* printer) const;
-  void GenerateSerializationCode(io::Printer* printer) const;
-  void GenerateSerializedSizeCode(io::Printer* printer) const;
-  void GenerateEqualsCode(io::Printer* printer) const;
-  void GenerateHashCode(io::Printer* printer) const;
+  void GenerateMembers(io::Printer* printer) const override;
+  void GenerateBuilderMembers(io::Printer* printer) const override;
+  void GenerateMergingCode(io::Printer* printer) const override;
+  void GenerateBuildingCode(io::Printer* printer) const override;
+  void GenerateParsingCode(io::Printer* printer) const override;
+  void GenerateSerializationCode(io::Printer* printer) const override;
+  void GenerateSerializedSizeCode(io::Printer* printer) const override;
+  void GenerateEqualsCode(io::Printer* printer) const override;
+  void GenerateHashCode(io::Printer* printer) const override;
 
  private:
   GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ImmutableEnumOneofFieldGenerator);
diff --git a/src/google/protobuf/compiler/java/java_extension.h b/src/google/protobuf/compiler/java/java_extension.h
index ab87890..164edfb 100644
--- a/src/google/protobuf/compiler/java/java_extension.h
+++ b/src/google/protobuf/compiler/java/java_extension.h
@@ -94,9 +94,9 @@
                                        Context* context);
   virtual ~ImmutableExtensionGenerator();
 
-  virtual void Generate(io::Printer* printer);
-  virtual int GenerateNonNestedInitializationCode(io::Printer* printer);
-  virtual int GenerateRegistrationCode(io::Printer* printer);
+  virtual void Generate(io::Printer* printer) override;
+  virtual int GenerateNonNestedInitializationCode(io::Printer* printer) override;
+  virtual int GenerateRegistrationCode(io::Printer* printer) override;
 
  protected:
   const FieldDescriptor* descriptor_;
diff --git a/src/google/protobuf/compiler/java/java_extension_lite.h b/src/google/protobuf/compiler/java/java_extension_lite.h
index 410781d..beda4f9 100644
--- a/src/google/protobuf/compiler/java/java_extension_lite.h
+++ b/src/google/protobuf/compiler/java/java_extension_lite.h
@@ -51,13 +51,14 @@
                                            Context* context);
   virtual ~ImmutableExtensionLiteGenerator();
 
-  virtual void Generate(io::Printer* printer);
+  virtual void Generate(io::Printer* printer) override;
 
   // Returns an estimate of the number of bytes the printed code will compile to
-  virtual int GenerateNonNestedInitializationCode(io::Printer* printer);
+  virtual int GenerateNonNestedInitializationCode(
+      io::Printer* printer) override;
 
   // Returns an estimate of the number of bytes the printed code will compile to
-  virtual int GenerateRegistrationCode(io::Printer* printer);
+  virtual int GenerateRegistrationCode(io::Printer* printer) override;
 
  private:
   const FieldDescriptor* descriptor_;
diff --git a/src/google/protobuf/compiler/java/java_generator_factory.h b/src/google/protobuf/compiler/java/java_generator_factory.h
index 16688a5..e64a45d 100644
--- a/src/google/protobuf/compiler/java/java_generator_factory.h
+++ b/src/google/protobuf/compiler/java/java_generator_factory.h
@@ -81,13 +81,13 @@
   virtual ~ImmutableGeneratorFactory();
 
   virtual MessageGenerator* NewMessageGenerator(
-      const Descriptor* descriptor) const;
+      const Descriptor* descriptor) const override;
 
   virtual ExtensionGenerator* NewExtensionGenerator(
-      const FieldDescriptor* descriptor) const;
+      const FieldDescriptor* descriptor) const override;
 
   virtual ServiceGenerator* NewServiceGenerator(
-      const ServiceDescriptor* descriptor) const;
+      const ServiceDescriptor* descriptor) const override;
 
  private:
   Context* context_;
diff --git a/src/google/protobuf/compiler/java/java_helpers.h b/src/google/protobuf/compiler/java/java_helpers.h
index 13dd903..5dc25d6 100644
--- a/src/google/protobuf/compiler/java/java_helpers.h
+++ b/src/google/protobuf/compiler/java/java_helpers.h
@@ -155,6 +155,7 @@
 // Whether we should generate multiple java files for messages.
 inline bool MultipleJavaFiles(const FileDescriptor* descriptor,
                               bool immutable) {
+  (void) immutable;
   return descriptor->options().java_multiple_files();
 }
 
@@ -244,15 +245,15 @@
 bool IsByteStringWithCustomDefaultValue(const FieldDescriptor* field);
 
 // Does this message class have descriptor and reflection methods?
-inline bool HasDescriptorMethods(const Descriptor* descriptor,
+inline bool HasDescriptorMethods(const Descriptor* /* descriptor */,
                                  bool enforce_lite) {
   return !enforce_lite;
 }
-inline bool HasDescriptorMethods(const EnumDescriptor* descriptor,
+inline bool HasDescriptorMethods(const EnumDescriptor* /* descriptor */,
                                  bool enforce_lite) {
   return !enforce_lite;
 }
-inline bool HasDescriptorMethods(const FileDescriptor* descriptor,
+inline bool HasDescriptorMethods(const FileDescriptor* /* descriptor */,
                                  bool enforce_lite) {
   return !enforce_lite;
 }
diff --git a/src/google/protobuf/compiler/java/java_map_field.h b/src/google/protobuf/compiler/java/java_map_field.h
index b52b7e9..98d9249 100644
--- a/src/google/protobuf/compiler/java/java_map_field.h
+++ b/src/google/protobuf/compiler/java/java_map_field.h
@@ -65,7 +65,7 @@
   void GenerateHashCode(io::Printer* printer) const override;
   void GenerateKotlinDslMembers(io::Printer* printer) const override;
 
-  std::string GetBoxedType() const;
+  std::string GetBoxedType() const override;
 
  private:
   const FieldDescriptor* descriptor_;
diff --git a/src/google/protobuf/compiler/java/java_message.cc b/src/google/protobuf/compiler/java/java_message.cc
index b7df10d..ebd57a7 100644
--- a/src/google/protobuf/compiler/java/java_message.cc
+++ b/src/google/protobuf/compiler/java/java_message.cc
@@ -1409,7 +1409,7 @@
       "@com.google.protobuf.kotlin.ProtoDslMarker\n");
   printer->Print(
       "class Dsl private constructor(\n"
-      "  @kotlin.jvm.JvmField private val _builder: $message$.Builder\n"
+      "  private val _builder: $message$.Builder\n"
       ") {\n"
       "  companion object {\n"
       "    @kotlin.jvm.JvmSynthetic\n"
diff --git a/src/google/protobuf/compiler/java/java_message_field.h b/src/google/protobuf/compiler/java/java_message_field.h
index 891bcc6..60acb19 100644
--- a/src/google/protobuf/compiler/java/java_message_field.h
+++ b/src/google/protobuf/compiler/java/java_message_field.h
@@ -65,25 +65,25 @@
 
   // implements ImmutableFieldGenerator
   // ---------------------------------------
-  int GetNumBitsForMessage() const;
-  int GetNumBitsForBuilder() const;
-  void GenerateInterfaceMembers(io::Printer* printer) const;
-  void GenerateMembers(io::Printer* printer) const;
-  void GenerateBuilderMembers(io::Printer* printer) const;
-  void GenerateInitializationCode(io::Printer* printer) const;
-  void GenerateBuilderClearCode(io::Printer* printer) const;
-  void GenerateMergingCode(io::Printer* printer) const;
-  void GenerateBuildingCode(io::Printer* printer) const;
-  void GenerateParsingCode(io::Printer* printer) const;
-  void GenerateParsingDoneCode(io::Printer* printer) const;
-  void GenerateSerializationCode(io::Printer* printer) const;
-  void GenerateSerializedSizeCode(io::Printer* printer) const;
-  void GenerateFieldBuilderInitializationCode(io::Printer* printer) const;
-  void GenerateEqualsCode(io::Printer* printer) const;
-  void GenerateHashCode(io::Printer* printer) const;
-  void GenerateKotlinDslMembers(io::Printer* printer) const;
+  int GetNumBitsForMessage() const override;
+  int GetNumBitsForBuilder() const override;
+  void GenerateInterfaceMembers(io::Printer* printer) const override;
+  void GenerateMembers(io::Printer* printer) const override;
+  void GenerateBuilderMembers(io::Printer* printer) const override;
+  void GenerateInitializationCode(io::Printer* printer) const override;
+  void GenerateBuilderClearCode(io::Printer* printer) const override;
+  void GenerateMergingCode(io::Printer* printer) const override;
+  void GenerateBuildingCode(io::Printer* printer) const override;
+  void GenerateParsingCode(io::Printer* printer) const override;
+  void GenerateParsingDoneCode(io::Printer* printer) const override;
+  void GenerateSerializationCode(io::Printer* printer) const override;
+  void GenerateSerializedSizeCode(io::Printer* printer) const override;
+  void GenerateFieldBuilderInitializationCode(io::Printer* printer) const override;
+  void GenerateEqualsCode(io::Printer* printer) const override;
+  void GenerateHashCode(io::Printer* printer) const override;
+  void GenerateKotlinDslMembers(io::Printer* printer) const override;
 
-  std::string GetBoxedType() const;
+  std::string GetBoxedType() const override;
 
  protected:
   const FieldDescriptor* descriptor_;
@@ -111,13 +111,13 @@
                                       Context* context);
   ~ImmutableMessageOneofFieldGenerator();
 
-  void GenerateMembers(io::Printer* printer) const;
-  void GenerateBuilderMembers(io::Printer* printer) const;
-  void GenerateBuildingCode(io::Printer* printer) const;
-  void GenerateMergingCode(io::Printer* printer) const;
-  void GenerateParsingCode(io::Printer* printer) const;
-  void GenerateSerializationCode(io::Printer* printer) const;
-  void GenerateSerializedSizeCode(io::Printer* printer) const;
+  void GenerateMembers(io::Printer* printer) const override;
+  void GenerateBuilderMembers(io::Printer* printer) const override;
+  void GenerateBuildingCode(io::Printer* printer) const override;
+  void GenerateMergingCode(io::Printer* printer) const override;
+  void GenerateParsingCode(io::Printer* printer) const override;
+  void GenerateSerializationCode(io::Printer* printer) const override;
+  void GenerateSerializedSizeCode(io::Printer* printer) const override;
 
  private:
   GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ImmutableMessageOneofFieldGenerator);
diff --git a/src/google/protobuf/compiler/java/java_message_field_lite.h b/src/google/protobuf/compiler/java/java_message_field_lite.h
index 3195b09..8f81f60 100644
--- a/src/google/protobuf/compiler/java/java_message_field_lite.h
+++ b/src/google/protobuf/compiler/java/java_message_field_lite.h
@@ -66,16 +66,16 @@
 
   // implements ImmutableFieldLiteGenerator
   // ------------------------------------
-  int GetNumBitsForMessage() const;
-  void GenerateInterfaceMembers(io::Printer* printer) const;
-  void GenerateMembers(io::Printer* printer) const;
-  void GenerateBuilderMembers(io::Printer* printer) const;
-  void GenerateInitializationCode(io::Printer* printer) const;
+  int GetNumBitsForMessage() const override;
+  void GenerateInterfaceMembers(io::Printer* printer) const override;
+  void GenerateMembers(io::Printer* printer) const override;
+  void GenerateBuilderMembers(io::Printer* printer) const override;
+  void GenerateInitializationCode(io::Printer* printer) const override;
   void GenerateFieldInfo(io::Printer* printer,
-                         std::vector<uint16_t>* output) const;
-  void GenerateKotlinDslMembers(io::Printer* printer) const;
+                         std::vector<uint16_t>* output) const override;
+  void GenerateKotlinDslMembers(io::Printer* printer) const override;
 
-  std::string GetBoxedType() const;
+  std::string GetBoxedType() const override;
 
  protected:
   const FieldDescriptor* descriptor_;
@@ -95,10 +95,10 @@
                                           Context* context);
   ~ImmutableMessageOneofFieldLiteGenerator();
 
-  void GenerateMembers(io::Printer* printer) const;
-  void GenerateBuilderMembers(io::Printer* printer) const;
+  void GenerateMembers(io::Printer* printer) const override;
+  void GenerateBuilderMembers(io::Printer* printer) const override;
   void GenerateFieldInfo(io::Printer* printer,
-                         std::vector<uint16_t>* output) const;
+                         std::vector<uint16_t>* output) const override;
 
  private:
   GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ImmutableMessageOneofFieldLiteGenerator);
diff --git a/src/google/protobuf/compiler/java/java_message_lite.cc b/src/google/protobuf/compiler/java/java_message_lite.cc
index 8558a66..8f93499 100644
--- a/src/google/protobuf/compiler/java/java_message_lite.cc
+++ b/src/google/protobuf/compiler/java/java_message_lite.cc
@@ -732,7 +732,7 @@
       "@com.google.protobuf.kotlin.ProtoDslMarker\n");
   printer->Print(
       "class Dsl private constructor(\n"
-      "  @kotlin.jvm.JvmField private val _builder: $message$.Builder\n"
+      "  private val _builder: $message$.Builder\n"
       ") {\n"
       "  companion object {\n"
       "    @kotlin.jvm.JvmSynthetic\n"
diff --git a/src/google/protobuf/compiler/java/java_message_lite.h b/src/google/protobuf/compiler/java/java_message_lite.h
index 4dfa291..0af0cb8 100644
--- a/src/google/protobuf/compiler/java/java_message_lite.h
+++ b/src/google/protobuf/compiler/java/java_message_lite.h
@@ -50,12 +50,12 @@
   ImmutableMessageLiteGenerator(const Descriptor* descriptor, Context* context);
   virtual ~ImmutableMessageLiteGenerator();
 
-  virtual void Generate(io::Printer* printer);
-  virtual void GenerateInterface(io::Printer* printer);
-  virtual void GenerateExtensionRegistrationCode(io::Printer* printer);
+  virtual void Generate(io::Printer* printer) override;
+  virtual void GenerateInterface(io::Printer* printer) override;
+  virtual void GenerateExtensionRegistrationCode(io::Printer* printer) override;
   virtual void GenerateStaticVariables(io::Printer* printer,
-                                       int* bytecode_estimate);
-  virtual int GenerateStaticVariableInitializers(io::Printer* printer);
+                                       int* bytecode_estimate) override;
+  virtual int GenerateStaticVariableInitializers(io::Printer* printer) override;
   void GenerateKotlinDsl(io::Printer* printer) const override;
   void GenerateKotlinMembers(io::Printer* printer) const override;
   void GenerateTopLevelKotlinMembers(io::Printer* printer) const override;
diff --git a/src/google/protobuf/compiler/java/java_primitive_field.h b/src/google/protobuf/compiler/java/java_primitive_field.h
index 535c1f1..1f0eb8c 100644
--- a/src/google/protobuf/compiler/java/java_primitive_field.h
+++ b/src/google/protobuf/compiler/java/java_primitive_field.h
@@ -103,13 +103,13 @@
                                         int builderBitIndex, Context* context);
   ~ImmutablePrimitiveOneofFieldGenerator();
 
-  void GenerateMembers(io::Printer* printer) const;
-  void GenerateBuilderMembers(io::Printer* printer) const;
-  void GenerateBuildingCode(io::Printer* printer) const;
-  void GenerateMergingCode(io::Printer* printer) const;
-  void GenerateParsingCode(io::Printer* printer) const;
-  void GenerateSerializationCode(io::Printer* printer) const;
-  void GenerateSerializedSizeCode(io::Printer* printer) const;
+  void GenerateMembers(io::Printer* printer) const override;
+  void GenerateBuilderMembers(io::Printer* printer) const override;
+  void GenerateBuildingCode(io::Printer* printer) const override;
+  void GenerateMergingCode(io::Printer* printer) const override;
+  void GenerateParsingCode(io::Printer* printer) const override;
+  void GenerateSerializationCode(io::Printer* printer) const override;
+  void GenerateSerializedSizeCode(io::Printer* printer) const override;
 
  private:
   GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ImmutablePrimitiveOneofFieldGenerator);
diff --git a/src/google/protobuf/compiler/java/java_primitive_field_lite.h b/src/google/protobuf/compiler/java/java_primitive_field_lite.h
index d3744b1..dfafae3 100644
--- a/src/google/protobuf/compiler/java/java_primitive_field_lite.h
+++ b/src/google/protobuf/compiler/java/java_primitive_field_lite.h
@@ -95,11 +95,11 @@
                                             Context* context);
   ~ImmutablePrimitiveOneofFieldLiteGenerator();
 
-  void GenerateMembers(io::Printer* printer) const;
-  void GenerateBuilderMembers(io::Printer* printer) const;
+  void GenerateMembers(io::Printer* printer) const override;
+  void GenerateBuilderMembers(io::Printer* printer) const override;
 
   void GenerateFieldInfo(io::Printer* printer,
-                         std::vector<uint16_t>* output) const;
+                         std::vector<uint16_t>* output) const override;
 
  private:
   GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ImmutablePrimitiveOneofFieldLiteGenerator);
diff --git a/src/google/protobuf/compiler/java/java_service.h b/src/google/protobuf/compiler/java/java_service.h
index 1c82c16..fa9c92c 100644
--- a/src/google/protobuf/compiler/java/java_service.h
+++ b/src/google/protobuf/compiler/java/java_service.h
@@ -80,7 +80,7 @@
                             Context* context);
   virtual ~ImmutableServiceGenerator();
 
-  virtual void Generate(io::Printer* printer);
+  virtual void Generate(io::Printer* printer) override;
 
  private:
   // Generate the getDescriptorForType() method.
diff --git a/src/google/protobuf/compiler/java/java_string_field.cc b/src/google/protobuf/compiler/java/java_string_field.cc
index 8d72d95..9ebb771 100644
--- a/src/google/protobuf/compiler/java/java_string_field.cc
+++ b/src/google/protobuf/compiler/java/java_string_field.cc
@@ -80,6 +80,8 @@
       "  if (value == null) {\n"
       "    throw new NullPointerException();\n"
       "  }\n";
+  (*variables)["isStringEmpty"] = "com.google.protobuf.GeneratedMessage" +
+                                GeneratedCodeVersionSuffix() + ".isStringEmpty";
   (*variables)["writeString"] = "com.google.protobuf.GeneratedMessage" +
                                 GeneratedCodeVersionSuffix() + ".writeString";
   (*variables)["computeStringSize"] = "com.google.protobuf.GeneratedMessage" +
@@ -117,7 +119,7 @@
     (*variables)["clear_has_field_bit_builder"] = "";
 
     (*variables)["is_field_present_message"] =
-        "!get" + (*variables)["capitalized_name"] + "Bytes().isEmpty()";
+       "!" + (*variables)["isStringEmpty"] + "(" + (*variables)["name"] + "_)";
   }
 
   // For repeated builders, one bit is used for whether the array is immutable.
diff --git a/src/google/protobuf/compiler/java/java_string_field.h b/src/google/protobuf/compiler/java/java_string_field.h
index a98ea54..369dcda 100644
--- a/src/google/protobuf/compiler/java/java_string_field.h
+++ b/src/google/protobuf/compiler/java/java_string_field.h
@@ -65,25 +65,25 @@
 
   // implements ImmutableFieldGenerator
   // ---------------------------------------
-  int GetNumBitsForMessage() const;
-  int GetNumBitsForBuilder() const;
-  void GenerateInterfaceMembers(io::Printer* printer) const;
-  void GenerateMembers(io::Printer* printer) const;
-  void GenerateBuilderMembers(io::Printer* printer) const;
-  void GenerateInitializationCode(io::Printer* printer) const;
-  void GenerateBuilderClearCode(io::Printer* printer) const;
-  void GenerateMergingCode(io::Printer* printer) const;
-  void GenerateBuildingCode(io::Printer* printer) const;
-  void GenerateParsingCode(io::Printer* printer) const;
-  void GenerateParsingDoneCode(io::Printer* printer) const;
-  void GenerateSerializationCode(io::Printer* printer) const;
-  void GenerateSerializedSizeCode(io::Printer* printer) const;
-  void GenerateFieldBuilderInitializationCode(io::Printer* printer) const;
-  void GenerateEqualsCode(io::Printer* printer) const;
-  void GenerateHashCode(io::Printer* printer) const;
-  void GenerateKotlinDslMembers(io::Printer* printer) const;
+  int GetNumBitsForMessage() const override;
+  int GetNumBitsForBuilder() const override;
+  void GenerateInterfaceMembers(io::Printer* printer) const override;
+  void GenerateMembers(io::Printer* printer) const override;
+  void GenerateBuilderMembers(io::Printer* printer) const override;
+  void GenerateInitializationCode(io::Printer* printer) const override;
+  void GenerateBuilderClearCode(io::Printer* printer) const override;
+  void GenerateMergingCode(io::Printer* printer) const override;
+  void GenerateBuildingCode(io::Printer* printer) const override;
+  void GenerateParsingCode(io::Printer* printer) const override;
+  void GenerateParsingDoneCode(io::Printer* printer) const override;
+  void GenerateSerializationCode(io::Printer* printer) const override;
+  void GenerateSerializedSizeCode(io::Printer* printer) const override;
+  void GenerateFieldBuilderInitializationCode(io::Printer* printer) const override;
+  void GenerateEqualsCode(io::Printer* printer) const override;
+  void GenerateHashCode(io::Printer* printer) const override;
+  void GenerateKotlinDslMembers(io::Printer* printer) const override;
 
-  std::string GetBoxedType() const;
+  std::string GetBoxedType() const override;
 
  protected:
   const FieldDescriptor* descriptor_;
@@ -103,13 +103,13 @@
   ~ImmutableStringOneofFieldGenerator();
 
  private:
-  void GenerateMembers(io::Printer* printer) const;
-  void GenerateBuilderMembers(io::Printer* printer) const;
-  void GenerateMergingCode(io::Printer* printer) const;
-  void GenerateBuildingCode(io::Printer* printer) const;
-  void GenerateParsingCode(io::Printer* printer) const;
-  void GenerateSerializationCode(io::Printer* printer) const;
-  void GenerateSerializedSizeCode(io::Printer* printer) const;
+  void GenerateMembers(io::Printer* printer) const override;
+  void GenerateBuilderMembers(io::Printer* printer) const override;
+  void GenerateMergingCode(io::Printer* printer) const override;
+  void GenerateBuildingCode(io::Printer* printer) const override;
+  void GenerateParsingCode(io::Printer* printer) const override;
+  void GenerateSerializationCode(io::Printer* printer) const override;
+  void GenerateSerializedSizeCode(io::Printer* printer) const override;
 
   GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ImmutableStringOneofFieldGenerator);
 };
diff --git a/src/google/protobuf/compiler/js/js_generator.cc b/src/google/protobuf/compiler/js/js_generator.cc
index 32c7ae5..cfd0e03 100644
--- a/src/google/protobuf/compiler/js/js_generator.cc
+++ b/src/google/protobuf/compiler/js/js_generator.cc
@@ -94,10 +94,6 @@
   return false;
 }
 
-bool StrEndsWith(StringPiece sp, StringPiece x) {
-  return sp.size() >= x.size() && sp.substr(sp.size() - x.size()) == x;
-}
-
 std::string GetSnakeFilename(const std::string& filename) {
   std::string snake_name = filename;
   ReplaceCharacters(&snake_name, "/", '_');
diff --git a/src/google/protobuf/compiler/parser.cc b/src/google/protobuf/compiler/parser.cc
index 9c4e1e4..b8659b7 100644
--- a/src/google/protobuf/compiler/parser.cc
+++ b/src/google/protobuf/compiler/parser.cc
@@ -97,19 +97,19 @@
   static const char kSuffix[] = "Entry";
   result.reserve(field_name.size() + sizeof(kSuffix));
   bool cap_next = true;
-  for (int i = 0; i < field_name.size(); ++i) {
-    if (field_name[i] == '_') {
+  for (const char field_name_char : field_name) {
+    if (field_name_char == '_') {
       cap_next = true;
     } else if (cap_next) {
       // Note: Do not use ctype.h due to locales.
-      if ('a' <= field_name[i] && field_name[i] <= 'z') {
-        result.push_back(field_name[i] - 'a' + 'A');
+      if ('a' <= field_name_char && field_name_char <= 'z') {
+        result.push_back(field_name_char - 'a' + 'A');
       } else {
-        result.push_back(field_name[i]);
+        result.push_back(field_name_char);
       }
       cap_next = false;
     } else {
-      result.push_back(field_name[i]);
+      result.push_back(field_name_char);
     }
   }
   result.append(kSuffix);
@@ -131,8 +131,8 @@
     return false;
   }
   // Must not contains underscore.
-  for (int i = 1; i < name.length(); i++) {
-    if (name[i] == '_') {
+  for (const char c : name) {
+    if (c == '_') {
       return false;
     }
   }
@@ -140,8 +140,7 @@
 }
 
 bool IsUpperUnderscore(const std::string& name) {
-  for (int i = 0; i < name.length(); i++) {
-    const char c = name[i];
+  for (const char c : name) {
     if (!IsUppercase(c) && c != '_' && !IsNumber(c)) {
       return false;
     }
@@ -150,8 +149,7 @@
 }
 
 bool IsLowerUnderscore(const std::string& name) {
-  for (int i = 0; i < name.length(); i++) {
-    const char c = name[i];
+  for (const char c : name) {
     if (!IsLowercase(c) && c != '_' && !IsNumber(c)) {
       return false;
     }
diff --git a/src/google/protobuf/compiler/parser_unittest.cc b/src/google/protobuf/compiler/parser_unittest.cc
index 32bf1b3..c942393 100644
--- a/src/google/protobuf/compiler/parser_unittest.cc
+++ b/src/google/protobuf/compiler/parser_unittest.cc
@@ -88,7 +88,7 @@
   // implements ErrorCollector ---------------------------------------
   void AddError(const std::string& filename, const std::string& element_name,
                 const Message* descriptor, ErrorLocation location,
-                const std::string& message) {
+                const std::string& message) override {
     int line, column;
     if (location == DescriptorPool::ErrorCollector::IMPORT) {
       source_locations_.FindImport(descriptor, element_name, &line, &column);
@@ -2588,7 +2588,7 @@
     return true;
   }
 
-  virtual void TearDown() {
+  virtual void TearDown() override {
     EXPECT_TRUE(spans_.empty()) << "Forgot to call HasSpan() for:\n"
                                 << spans_.begin()->second->DebugString();
   }
diff --git a/src/google/protobuf/compiler/plugin.cc b/src/google/protobuf/compiler/plugin.cc
index 8e3d289..a8e40cd 100644
--- a/src/google/protobuf/compiler/plugin.cc
+++ b/src/google/protobuf/compiler/plugin.cc
@@ -72,14 +72,14 @@
 
   // implements GeneratorContext --------------------------------------
 
-  virtual io::ZeroCopyOutputStream* Open(const std::string& filename) {
+  virtual io::ZeroCopyOutputStream* Open(const std::string& filename) override {
     CodeGeneratorResponse::File* file = response_->add_file();
     file->set_name(filename);
     return new io::StringOutputStream(file->mutable_content());
   }
 
   virtual io::ZeroCopyOutputStream* OpenForInsert(
-      const std::string& filename, const std::string& insertion_point) {
+      const std::string& filename, const std::string& insertion_point) override {
     CodeGeneratorResponse::File* file = response_->add_file();
     file->set_name(filename);
     file->set_insertion_point(insertion_point);
@@ -88,7 +88,7 @@
 
   virtual io::ZeroCopyOutputStream* OpenForInsertWithGeneratedCodeInfo(
       const std::string& filename, const std::string& insertion_point,
-      const google::protobuf::GeneratedCodeInfo& info) {
+      const google::protobuf::GeneratedCodeInfo& info) override {
     CodeGeneratorResponse::File* file = response_->add_file();
     file->set_name(filename);
     file->set_insertion_point(insertion_point);
@@ -96,11 +96,11 @@
     return new io::StringOutputStream(file->mutable_content());
   }
 
-  void ListParsedFiles(std::vector<const FileDescriptor*>* output) {
+  void ListParsedFiles(std::vector<const FileDescriptor*>* output) override {
     *output = parsed_files_;
   }
 
-  void GetCompilerVersion(Version* version) const {
+  void GetCompilerVersion(Version* version) const override {
     *version = compiler_version_;
   }
 
diff --git a/src/google/protobuf/compiler/plugin.pb.cc b/src/google/protobuf/compiler/plugin.pb.cc
index 9f09ec2..9f35b1c 100644
--- a/src/google/protobuf/compiler/plugin.pb.cc
+++ b/src/google/protobuf/compiler/plugin.pb.cc
@@ -258,7 +258,7 @@
   // @@protoc_insertion_point(copy_constructor:google.protobuf.compiler.Version)
 }
 
-inline void Version::SharedCtor() {
+void Version::SharedCtor() {
 suffix_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
 ::memset(reinterpret_cast<char*>(this) + static_cast<size_t>(
     reinterpret_cast<char*>(&major_) - reinterpret_cast<char*>(this)),
@@ -581,7 +581,7 @@
   // @@protoc_insertion_point(copy_constructor:google.protobuf.compiler.CodeGeneratorRequest)
 }
 
-inline void CodeGeneratorRequest::SharedCtor() {
+void CodeGeneratorRequest::SharedCtor() {
 parameter_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
 compiler_version_ = nullptr;
 }
@@ -937,7 +937,7 @@
   // @@protoc_insertion_point(copy_constructor:google.protobuf.compiler.CodeGeneratorResponse.File)
 }
 
-inline void CodeGeneratorResponse_File::SharedCtor() {
+void CodeGeneratorResponse_File::SharedCtor() {
 name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
 insertion_point_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
 content_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
@@ -1280,7 +1280,7 @@
   // @@protoc_insertion_point(copy_constructor:google.protobuf.compiler.CodeGeneratorResponse)
 }
 
-inline void CodeGeneratorResponse::SharedCtor() {
+void CodeGeneratorResponse::SharedCtor() {
 error_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
 supported_features_ = uint64_t{0u};
 }
diff --git a/src/google/protobuf/compiler/plugin.pb.h b/src/google/protobuf/compiler/plugin.pb.h
index d6124da..d230cd4 100644
--- a/src/google/protobuf/compiler/plugin.pb.h
+++ b/src/google/protobuf/compiler/plugin.pb.h
@@ -8,12 +8,12 @@
 #include <string>
 
 #include <google/protobuf/port_def.inc>
-#if PROTOBUF_VERSION < 3015000
+#if PROTOBUF_VERSION < 3017000
 #error This file was generated by a newer version of protoc which is
 #error incompatible with your Protocol Buffer headers. Please update
 #error your headers.
 #endif
-#if 3015008 < PROTOBUF_MIN_PROTOC_VERSION
+#if 3017003 < 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.
@@ -60,7 +60,7 @@
   static const ::PROTOBUF_NAMESPACE_ID::internal::SerializationTable serialization_table[];
   static const ::PROTOBUF_NAMESPACE_ID::uint32 offsets[];
 };
-extern PROTOC_EXPORT const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto;
+PROTOC_EXPORT extern const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto;
 PROTOBUF_NAMESPACE_OPEN
 namespace compiler {
 class CodeGeneratorRequest;
diff --git a/src/google/protobuf/descriptor.pb.cc b/src/google/protobuf/descriptor.pb.cc
index f5eb0b3..6e2afc0 100644
--- a/src/google/protobuf/descriptor.pb.cc
+++ b/src/google/protobuf/descriptor.pb.cc
@@ -393,9 +393,9 @@
 constexpr SourceCodeInfo_Location::SourceCodeInfo_Location(
   ::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized)
   : path_()
-  , _path_cached_byte_size_()
+  , _path_cached_byte_size_(0)
   , span_()
-  , _span_cached_byte_size_()
+  , _span_cached_byte_size_(0)
   , leading_detached_comments_()
   , leading_comments_(&::PROTOBUF_NAMESPACE_ID::internal::fixed_address_empty_string)
   , trailing_comments_(&::PROTOBUF_NAMESPACE_ID::internal::fixed_address_empty_string){}
@@ -423,7 +423,7 @@
 constexpr GeneratedCodeInfo_Annotation::GeneratedCodeInfo_Annotation(
   ::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized)
   : path_()
-  , _path_cached_byte_size_()
+  , _path_cached_byte_size_(0)
   , source_file_(&::PROTOBUF_NAMESPACE_ID::internal::fixed_address_empty_string)
   , begin_(0)
   , end_(0){}
@@ -1282,7 +1282,7 @@
   // @@protoc_insertion_point(copy_constructor:google.protobuf.FileDescriptorSet)
 }
 
-inline void FileDescriptorSet::SharedCtor() {
+void FileDescriptorSet::SharedCtor() {
 }
 
 FileDescriptorSet::~FileDescriptorSet() {
@@ -1532,7 +1532,7 @@
   // @@protoc_insertion_point(copy_constructor:google.protobuf.FileDescriptorProto)
 }
 
-inline void FileDescriptorProto::SharedCtor() {
+void FileDescriptorProto::SharedCtor() {
 name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
 package_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
 syntax_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
@@ -2159,7 +2159,7 @@
   // @@protoc_insertion_point(copy_constructor:google.protobuf.DescriptorProto.ExtensionRange)
 }
 
-inline void DescriptorProto_ExtensionRange::SharedCtor() {
+void DescriptorProto_ExtensionRange::SharedCtor() {
 ::memset(reinterpret_cast<char*>(this) + static_cast<size_t>(
     reinterpret_cast<char*>(&options_) - reinterpret_cast<char*>(this)),
     0, static_cast<size_t>(reinterpret_cast<char*>(&end_) -
@@ -2430,7 +2430,7 @@
   // @@protoc_insertion_point(copy_constructor:google.protobuf.DescriptorProto.ReservedRange)
 }
 
-inline void DescriptorProto_ReservedRange::SharedCtor() {
+void DescriptorProto_ReservedRange::SharedCtor() {
 ::memset(reinterpret_cast<char*>(this) + static_cast<size_t>(
     reinterpret_cast<char*>(&start_) - reinterpret_cast<char*>(this)),
     0, static_cast<size_t>(reinterpret_cast<char*>(&end_) -
@@ -2695,7 +2695,7 @@
   // @@protoc_insertion_point(copy_constructor:google.protobuf.DescriptorProto)
 }
 
-inline void DescriptorProto::SharedCtor() {
+void DescriptorProto::SharedCtor() {
 name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
 options_ = nullptr;
 }
@@ -3206,7 +3206,7 @@
   // @@protoc_insertion_point(copy_constructor:google.protobuf.ExtensionRangeOptions)
 }
 
-inline void ExtensionRangeOptions::SharedCtor() {
+void ExtensionRangeOptions::SharedCtor() {
 }
 
 ExtensionRangeOptions::~ExtensionRangeOptions() {
@@ -3481,7 +3481,7 @@
   // @@protoc_insertion_point(copy_constructor:google.protobuf.FieldDescriptorProto)
 }
 
-inline void FieldDescriptorProto::SharedCtor() {
+void FieldDescriptorProto::SharedCtor() {
 name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
 extendee_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
 type_name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
@@ -4073,7 +4073,7 @@
   // @@protoc_insertion_point(copy_constructor:google.protobuf.OneofDescriptorProto)
 }
 
-inline void OneofDescriptorProto::SharedCtor() {
+void OneofDescriptorProto::SharedCtor() {
 name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
 options_ = nullptr;
 }
@@ -4330,7 +4330,7 @@
   // @@protoc_insertion_point(copy_constructor:google.protobuf.EnumDescriptorProto.EnumReservedRange)
 }
 
-inline void EnumDescriptorProto_EnumReservedRange::SharedCtor() {
+void EnumDescriptorProto_EnumReservedRange::SharedCtor() {
 ::memset(reinterpret_cast<char*>(this) + static_cast<size_t>(
     reinterpret_cast<char*>(&start_) - reinterpret_cast<char*>(this)),
     0, static_cast<size_t>(reinterpret_cast<char*>(&end_) -
@@ -4585,7 +4585,7 @@
   // @@protoc_insertion_point(copy_constructor:google.protobuf.EnumDescriptorProto)
 }
 
-inline void EnumDescriptorProto::SharedCtor() {
+void EnumDescriptorProto::SharedCtor() {
 name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
 options_ = nullptr;
 }
@@ -4959,7 +4959,7 @@
   // @@protoc_insertion_point(copy_constructor:google.protobuf.EnumValueDescriptorProto)
 }
 
-inline void EnumValueDescriptorProto::SharedCtor() {
+void EnumValueDescriptorProto::SharedCtor() {
 name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
 ::memset(reinterpret_cast<char*>(this) + static_cast<size_t>(
     reinterpret_cast<char*>(&options_) - reinterpret_cast<char*>(this)),
@@ -5263,7 +5263,7 @@
   // @@protoc_insertion_point(copy_constructor:google.protobuf.ServiceDescriptorProto)
 }
 
-inline void ServiceDescriptorProto::SharedCtor() {
+void ServiceDescriptorProto::SharedCtor() {
 name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
 options_ = nullptr;
 }
@@ -5589,7 +5589,7 @@
   // @@protoc_insertion_point(copy_constructor:google.protobuf.MethodDescriptorProto)
 }
 
-inline void MethodDescriptorProto::SharedCtor() {
+void MethodDescriptorProto::SharedCtor() {
 name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
 input_type_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
 output_type_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
@@ -6096,7 +6096,7 @@
   // @@protoc_insertion_point(copy_constructor:google.protobuf.FileOptions)
 }
 
-inline void FileOptions::SharedCtor() {
+void FileOptions::SharedCtor() {
 java_package_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
 java_outer_classname_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
 go_package_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
@@ -7029,7 +7029,7 @@
   // @@protoc_insertion_point(copy_constructor:google.protobuf.MessageOptions)
 }
 
-inline void MessageOptions::SharedCtor() {
+void MessageOptions::SharedCtor() {
 ::memset(reinterpret_cast<char*>(this) + static_cast<size_t>(
     reinterpret_cast<char*>(&message_set_wire_format_) - reinterpret_cast<char*>(this)),
     0, static_cast<size_t>(reinterpret_cast<char*>(&map_entry_) -
@@ -7375,7 +7375,7 @@
   // @@protoc_insertion_point(copy_constructor:google.protobuf.FieldOptions)
 }
 
-inline void FieldOptions::SharedCtor() {
+void FieldOptions::SharedCtor() {
 ::memset(reinterpret_cast<char*>(this) + static_cast<size_t>(
     reinterpret_cast<char*>(&ctype_) - reinterpret_cast<char*>(this)),
     0, static_cast<size_t>(reinterpret_cast<char*>(&jstype_) -
@@ -7759,7 +7759,7 @@
   // @@protoc_insertion_point(copy_constructor:google.protobuf.OneofOptions)
 }
 
-inline void OneofOptions::SharedCtor() {
+void OneofOptions::SharedCtor() {
 }
 
 OneofOptions::~OneofOptions() {
@@ -7976,7 +7976,7 @@
   // @@protoc_insertion_point(copy_constructor:google.protobuf.EnumOptions)
 }
 
-inline void EnumOptions::SharedCtor() {
+void EnumOptions::SharedCtor() {
 ::memset(reinterpret_cast<char*>(this) + static_cast<size_t>(
     reinterpret_cast<char*>(&allow_alias_) - reinterpret_cast<char*>(this)),
     0, static_cast<size_t>(reinterpret_cast<char*>(&deprecated_) -
@@ -8259,7 +8259,7 @@
   // @@protoc_insertion_point(copy_constructor:google.protobuf.EnumValueOptions)
 }
 
-inline void EnumValueOptions::SharedCtor() {
+void EnumValueOptions::SharedCtor() {
 deprecated_ = false;
 }
 
@@ -8503,7 +8503,7 @@
   // @@protoc_insertion_point(copy_constructor:google.protobuf.ServiceOptions)
 }
 
-inline void ServiceOptions::SharedCtor() {
+void ServiceOptions::SharedCtor() {
 deprecated_ = false;
 }
 
@@ -8752,7 +8752,7 @@
   // @@protoc_insertion_point(copy_constructor:google.protobuf.MethodOptions)
 }
 
-inline void MethodOptions::SharedCtor() {
+void MethodOptions::SharedCtor() {
 ::memset(reinterpret_cast<char*>(this) + static_cast<size_t>(
     reinterpret_cast<char*>(&deprecated_) - reinterpret_cast<char*>(this)),
     0, static_cast<size_t>(reinterpret_cast<char*>(&idempotency_level_) -
@@ -9051,7 +9051,7 @@
   // @@protoc_insertion_point(copy_constructor:google.protobuf.UninterpretedOption.NamePart)
 }
 
-inline void UninterpretedOption_NamePart::SharedCtor() {
+void UninterpretedOption_NamePart::SharedCtor() {
 name_part_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
 is_extension_ = false;
 }
@@ -9342,7 +9342,7 @@
   // @@protoc_insertion_point(copy_constructor:google.protobuf.UninterpretedOption)
 }
 
-inline void UninterpretedOption::SharedCtor() {
+void UninterpretedOption::SharedCtor() {
 identifier_value_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
 string_value_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
 aggregate_value_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
@@ -9770,7 +9770,7 @@
   // @@protoc_insertion_point(copy_constructor:google.protobuf.SourceCodeInfo.Location)
 }
 
-inline void SourceCodeInfo_Location::SharedCtor() {
+void SourceCodeInfo_Location::SharedCtor() {
 leading_comments_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
 trailing_comments_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
 }
@@ -10138,7 +10138,7 @@
   // @@protoc_insertion_point(copy_constructor:google.protobuf.SourceCodeInfo)
 }
 
-inline void SourceCodeInfo::SharedCtor() {
+void SourceCodeInfo::SharedCtor() {
 }
 
 SourceCodeInfo::~SourceCodeInfo() {
@@ -10342,7 +10342,7 @@
   // @@protoc_insertion_point(copy_constructor:google.protobuf.GeneratedCodeInfo.Annotation)
 }
 
-inline void GeneratedCodeInfo_Annotation::SharedCtor() {
+void GeneratedCodeInfo_Annotation::SharedCtor() {
 source_file_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
 ::memset(reinterpret_cast<char*>(this) + static_cast<size_t>(
     reinterpret_cast<char*>(&begin_) - reinterpret_cast<char*>(this)),
@@ -10652,7 +10652,7 @@
   // @@protoc_insertion_point(copy_constructor:google.protobuf.GeneratedCodeInfo)
 }
 
-inline void GeneratedCodeInfo::SharedCtor() {
+void GeneratedCodeInfo::SharedCtor() {
 }
 
 GeneratedCodeInfo::~GeneratedCodeInfo() {
diff --git a/src/google/protobuf/descriptor.pb.h b/src/google/protobuf/descriptor.pb.h
index 104b779..968b70c 100644
--- a/src/google/protobuf/descriptor.pb.h
+++ b/src/google/protobuf/descriptor.pb.h
@@ -8,12 +8,12 @@
 #include <string>
 
 #include <google/protobuf/port_def.inc>
-#if PROTOBUF_VERSION < 3015000
+#if PROTOBUF_VERSION < 3017000
 #error This file was generated by a newer version of protoc which is
 #error incompatible with your Protocol Buffer headers. Please update
 #error your headers.
 #endif
-#if 3015008 < PROTOBUF_MIN_PROTOC_VERSION
+#if 3017003 < 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.
@@ -53,7 +53,7 @@
   static const ::PROTOBUF_NAMESPACE_ID::internal::SerializationTable serialization_table[];
   static const ::PROTOBUF_NAMESPACE_ID::uint32 offsets[];
 };
-extern PROTOBUF_EXPORT const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable descriptor_table_google_2fprotobuf_2fdescriptor_2eproto;
+PROTOBUF_EXPORT extern const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable descriptor_table_google_2fprotobuf_2fdescriptor_2eproto;
 PROTOBUF_NAMESPACE_OPEN
 class DescriptorProto;
 struct DescriptorProtoDefaultTypeInternal;
diff --git a/src/google/protobuf/descriptor_unittest.cc b/src/google/protobuf/descriptor_unittest.cc
index 8438ec5..b98e7f7 100644
--- a/src/google/protobuf/descriptor_unittest.cc
+++ b/src/google/protobuf/descriptor_unittest.cc
@@ -206,7 +206,7 @@
   // implements ErrorCollector ---------------------------------------
   void AddError(const std::string& filename, const std::string& element_name,
                 const Message* descriptor, ErrorLocation location,
-                const std::string& message) {
+                const std::string& message) override {
     const char* location_name = nullptr;
     switch (location) {
       case NAME:
@@ -251,7 +251,7 @@
   // implements ErrorCollector ---------------------------------------
   void AddWarning(const std::string& filename, const std::string& element_name,
                   const Message* descriptor, ErrorLocation location,
-                  const std::string& message) {
+                  const std::string& message) override {
     const char* location_name = nullptr;
     switch (location) {
       case NAME:
@@ -299,7 +299,7 @@
 // Test simple files.
 class FileDescriptorTest : public testing::Test {
  protected:
-  virtual void SetUp() {
+  virtual void SetUp() override {
     // Build descriptors for the following definitions:
     //
     //   // in "foo.proto"
@@ -565,7 +565,7 @@
 class SimpleErrorCollector : public io::ErrorCollector {
  public:
   // implements ErrorCollector ---------------------------------------
-  void AddError(int line, int column, const std::string& message) {
+  void AddError(int line, int column, const std::string& message) override {
     last_error_ = StringPrintf("%d:%d:", line, column) + message;
   }
 
@@ -614,7 +614,7 @@
 // Test simple flat messages and fields.
 class DescriptorTest : public testing::Test {
  protected:
-  virtual void SetUp() {
+  virtual void SetUp() override {
     // Build descriptors for the following definitions:
     //
     //   // in "foo.proto"
@@ -1101,7 +1101,7 @@
 // Test simple flat messages and fields.
 class OneofDescriptorTest : public testing::Test {
  protected:
-  virtual void SetUp() {
+  virtual void SetUp() override {
     // Build descriptors for the following definitions:
     //
     //   package garply;
@@ -1192,7 +1192,7 @@
 
 class StylizedFieldNamesTest : public testing::Test {
  protected:
-  void SetUp() {
+  void SetUp() override {
     FileDescriptorProto file;
     file.set_name("foo.proto");
 
@@ -1361,7 +1361,7 @@
 // Test enum descriptors.
 class EnumDescriptorTest : public testing::Test {
  protected:
-  virtual void SetUp() {
+  virtual void SetUp() override {
     // Build descriptors for the following definitions:
     //
     //   // in "foo.proto"
@@ -1512,7 +1512,7 @@
 // Test service descriptors.
 class ServiceDescriptorTest : public testing::Test {
  protected:
-  virtual void SetUp() {
+  virtual void SetUp() override {
     // Build descriptors for the following messages and service:
     //    // in "foo.proto"
     //    message FooRequest  {}
@@ -1673,7 +1673,7 @@
 // Test nested types.
 class NestedDescriptorTest : public testing::Test {
  protected:
-  virtual void SetUp() {
+  virtual void SetUp() override {
     // Build descriptors for the following definitions:
     //
     //   // in "foo.proto"
@@ -1887,7 +1887,7 @@
 // Test extensions.
 class ExtensionDescriptorTest : public testing::Test {
  protected:
-  virtual void SetUp() {
+  virtual void SetUp() override {
     // Build descriptors for the following definitions:
     //
     //   enum Baz {}
@@ -2210,7 +2210,7 @@
 // Test reserved fields.
 class ReservedDescriptorTest : public testing::Test {
  protected:
-  virtual void SetUp() {
+  virtual void SetUp() override {
     // Build descriptors for the following definitions:
     //
     //   message Foo {
@@ -2288,7 +2288,7 @@
 // Test reserved enum fields.
 class ReservedEnumDescriptorTest : public testing::Test {
  protected:
-  virtual void SetUp() {
+  virtual void SetUp() override {
     // Build descriptors for the following definitions:
     //
     //   enum Foo {
@@ -2814,7 +2814,7 @@
   DescriptorPoolMode mode() { return std::get<0>(GetParam()); }
   const char* syntax() { return std::get<1>(GetParam()); }
 
-  virtual void SetUp() {
+  virtual void SetUp() override {
     FileDescriptorProto foo_proto, bar_proto;
 
     switch (mode()) {
@@ -6792,7 +6792,7 @@
 
   SimpleDescriptorDatabase database_;
 
-  virtual void SetUp() {
+  virtual void SetUp() override {
     AddToDatabase(
         &database_,
         "name: 'foo.proto' "
@@ -6824,7 +6824,7 @@
 
     // implements DescriptorDatabase ---------------------------------
     bool FindFileByName(const std::string& filename,
-                        FileDescriptorProto* output) {
+                        FileDescriptorProto* output) override {
       // error.proto and error2.proto cyclically import each other.
       if (filename == "error.proto") {
         output->Clear();
@@ -6841,12 +6841,12 @@
       }
     }
     bool FindFileContainingSymbol(const std::string& symbol_name,
-                                  FileDescriptorProto* output) {
+                                  FileDescriptorProto* output) override {
       return false;
     }
     bool FindFileContainingExtension(const std::string& containing_type,
                                      int field_number,
-                                     FileDescriptorProto* output) {
+                                     FileDescriptorProto* output) override {
       return false;
     }
   };
@@ -6869,18 +6869,18 @@
 
     // implements DescriptorDatabase ---------------------------------
     bool FindFileByName(const std::string& filename,
-                        FileDescriptorProto* output) {
+                        FileDescriptorProto* output) override {
       ++call_count_;
       return wrapped_db_->FindFileByName(filename, output);
     }
     bool FindFileContainingSymbol(const std::string& symbol_name,
-                                  FileDescriptorProto* output) {
+                                  FileDescriptorProto* output) override {
       ++call_count_;
       return wrapped_db_->FindFileContainingSymbol(symbol_name, output);
     }
     bool FindFileContainingExtension(const std::string& containing_type,
                                      int field_number,
-                                     FileDescriptorProto* output) {
+                                     FileDescriptorProto* output) override {
       ++call_count_;
       return wrapped_db_->FindFileContainingExtension(containing_type,
                                                       field_number, output);
@@ -6900,16 +6900,16 @@
 
     // implements DescriptorDatabase ---------------------------------
     bool FindFileByName(const std::string& filename,
-                        FileDescriptorProto* output) {
+                        FileDescriptorProto* output) override {
       return wrapped_db_->FindFileByName(filename, output);
     }
     bool FindFileContainingSymbol(const std::string& symbol_name,
-                                  FileDescriptorProto* output) {
+                                  FileDescriptorProto* output) override {
       return FindFileByName("foo.proto", output);
     }
     bool FindFileContainingExtension(const std::string& containing_type,
                                      int field_number,
-                                     FileDescriptorProto* output) {
+                                     FileDescriptorProto* output) override {
       return FindFileByName("foo.proto", output);
     }
   };
@@ -7185,7 +7185,7 @@
 
   // implements DescriptorDatabase ---------------------------------
   bool FindFileByName(const std::string& filename,
-                      FileDescriptorProto* output) {
+                      FileDescriptorProto* output) override {
     int file_num = -1;
     FullMatch(filename, "file", ".proto", &file_num);
     if (file_num > -1) {
@@ -7195,7 +7195,7 @@
     }
   }
   bool FindFileContainingSymbol(const std::string& symbol_name,
-                                FileDescriptorProto* output) {
+                                FileDescriptorProto* output) override {
     int file_num = -1;
     FullMatch(symbol_name, "Message", "", &file_num);
     if (file_num > 0) {
@@ -7206,7 +7206,7 @@
   }
   bool FindFileContainingExtension(const std::string& containing_type,
                                    int field_number,
-                                   FileDescriptorProto* output) {
+                                   FileDescriptorProto* output) override {
     return false;
   }
 
@@ -7292,7 +7292,7 @@
   virtual void AddError(const std::string& filename,
                         const std::string& element_name, const Message* message,
                         ErrorLocation location,
-                        const std::string& error_message) {
+                        const std::string& error_message) override {
     GOOGLE_LOG(FATAL) << "AddError() called unexpectedly: " << filename << " ["
                << element_name << "]: " << error_message;
   }
@@ -7307,7 +7307,7 @@
   SingletonSourceTree(const std::string& filename, const std::string& contents)
       : filename_(filename), contents_(contents) {}
 
-  virtual io::ZeroCopyInputStream* Open(const std::string& filename) {
+  virtual io::ZeroCopyInputStream* Open(const std::string& filename) override {
     return filename == filename_
                ? new io::ArrayInputStream(contents_.data(), contents_.size())
                : nullptr;
diff --git a/src/google/protobuf/duration.pb.cc b/src/google/protobuf/duration.pb.cc
index 9b9017a..94c1f0a 100644
--- a/src/google/protobuf/duration.pb.cc
+++ b/src/google/protobuf/duration.pb.cc
@@ -100,7 +100,7 @@
   // @@protoc_insertion_point(copy_constructor:google.protobuf.Duration)
 }
 
-inline void Duration::SharedCtor() {
+void Duration::SharedCtor() {
 ::memset(reinterpret_cast<char*>(this) + static_cast<size_t>(
     reinterpret_cast<char*>(&seconds_) - reinterpret_cast<char*>(this)),
     0, static_cast<size_t>(reinterpret_cast<char*>(&nanos_) -
diff --git a/src/google/protobuf/duration.pb.h b/src/google/protobuf/duration.pb.h
index 951cc00..b7bd056 100644
--- a/src/google/protobuf/duration.pb.h
+++ b/src/google/protobuf/duration.pb.h
@@ -8,12 +8,12 @@
 #include <string>
 
 #include <google/protobuf/port_def.inc>
-#if PROTOBUF_VERSION < 3015000
+#if PROTOBUF_VERSION < 3017000
 #error This file was generated by a newer version of protoc which is
 #error incompatible with your Protocol Buffer headers. Please update
 #error your headers.
 #endif
-#if 3015008 < PROTOBUF_MIN_PROTOC_VERSION
+#if 3017003 < 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.
@@ -52,7 +52,7 @@
   static const ::PROTOBUF_NAMESPACE_ID::internal::SerializationTable serialization_table[];
   static const ::PROTOBUF_NAMESPACE_ID::uint32 offsets[];
 };
-extern PROTOBUF_EXPORT const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable descriptor_table_google_2fprotobuf_2fduration_2eproto;
+PROTOBUF_EXPORT extern const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable descriptor_table_google_2fprotobuf_2fduration_2eproto;
 PROTOBUF_NAMESPACE_OPEN
 class Duration;
 struct DurationDefaultTypeInternal;
diff --git a/src/google/protobuf/dynamic_message_unittest.cc b/src/google/protobuf/dynamic_message_unittest.cc
index dcd5b88..e22926e 100644
--- a/src/google/protobuf/dynamic_message_unittest.cc
+++ b/src/google/protobuf/dynamic_message_unittest.cc
@@ -74,7 +74,7 @@
 
   DynamicMessageTest() : factory_(&pool_) {}
 
-  virtual void SetUp() {
+  virtual void SetUp() override {
     // We want to make sure that DynamicMessage works (particularly with
     // extensions) even if we use descriptors that are *not* from compiled-in
     // types, so we make copies of the descriptors for unittest.proto and
diff --git a/src/google/protobuf/empty.pb.h b/src/google/protobuf/empty.pb.h
index 542be1c..84d914d 100644
--- a/src/google/protobuf/empty.pb.h
+++ b/src/google/protobuf/empty.pb.h
@@ -8,12 +8,12 @@
 #include <string>
 
 #include <google/protobuf/port_def.inc>
-#if PROTOBUF_VERSION < 3015000
+#if PROTOBUF_VERSION < 3017000
 #error This file was generated by a newer version of protoc which is
 #error incompatible with your Protocol Buffer headers. Please update
 #error your headers.
 #endif
-#if 3015008 < PROTOBUF_MIN_PROTOC_VERSION
+#if 3017003 < 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.
@@ -52,7 +52,7 @@
   static const ::PROTOBUF_NAMESPACE_ID::internal::SerializationTable serialization_table[];
   static const ::PROTOBUF_NAMESPACE_ID::uint32 offsets[];
 };
-extern PROTOBUF_EXPORT const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable descriptor_table_google_2fprotobuf_2fempty_2eproto;
+PROTOBUF_EXPORT extern const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable descriptor_table_google_2fprotobuf_2fempty_2eproto;
 PROTOBUF_NAMESPACE_OPEN
 class Empty;
 struct EmptyDefaultTypeInternal;
diff --git a/src/google/protobuf/field_mask.pb.cc b/src/google/protobuf/field_mask.pb.cc
index 53f734d..988dd34 100644
--- a/src/google/protobuf/field_mask.pb.cc
+++ b/src/google/protobuf/field_mask.pb.cc
@@ -97,7 +97,7 @@
   // @@protoc_insertion_point(copy_constructor:google.protobuf.FieldMask)
 }
 
-inline void FieldMask::SharedCtor() {
+void FieldMask::SharedCtor() {
 }
 
 FieldMask::~FieldMask() {
diff --git a/src/google/protobuf/field_mask.pb.h b/src/google/protobuf/field_mask.pb.h
index b2d93d1..a46011a 100644
--- a/src/google/protobuf/field_mask.pb.h
+++ b/src/google/protobuf/field_mask.pb.h
@@ -8,12 +8,12 @@
 #include <string>
 
 #include <google/protobuf/port_def.inc>
-#if PROTOBUF_VERSION < 3015000
+#if PROTOBUF_VERSION < 3017000
 #error This file was generated by a newer version of protoc which is
 #error incompatible with your Protocol Buffer headers. Please update
 #error your headers.
 #endif
-#if 3015008 < PROTOBUF_MIN_PROTOC_VERSION
+#if 3017003 < 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.
@@ -52,7 +52,7 @@
   static const ::PROTOBUF_NAMESPACE_ID::internal::SerializationTable serialization_table[];
   static const ::PROTOBUF_NAMESPACE_ID::uint32 offsets[];
 };
-extern PROTOBUF_EXPORT const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable descriptor_table_google_2fprotobuf_2ffield_5fmask_2eproto;
+PROTOBUF_EXPORT extern const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable descriptor_table_google_2fprotobuf_2ffield_5fmask_2eproto;
 PROTOBUF_NAMESPACE_OPEN
 class FieldMask;
 struct FieldMaskDefaultTypeInternal;
diff --git a/src/google/protobuf/generated_message_table_driven.h b/src/google/protobuf/generated_message_table_driven.h
index a887fb6..178a0c1 100644
--- a/src/google/protobuf/generated_message_table_driven.h
+++ b/src/google/protobuf/generated_message_table_driven.h
@@ -266,7 +266,7 @@
   SerializeInternal(base, field_table + 1, num_fields, output);
 }
 
-uint8_t* SerializeInternalToArray(const uint8_t* base,
+PROTOBUF_EXPORT uint8_t* SerializeInternalToArray(const uint8_t* base,
                                   const FieldMetadata* table,
                                   int32_t num_fields, bool is_deterministic,
                                   uint8_t* buffer);
diff --git a/src/google/protobuf/io/coded_stream.h b/src/google/protobuf/io/coded_stream.h
index 6f48bf8..40896e7 100644
--- a/src/google/protobuf/io/coded_stream.h
+++ b/src/google/protobuf/io/coded_stream.h
@@ -136,8 +136,10 @@
 #elif defined(__FreeBSD__)
 #include <sys/endian.h>  // __BYTE_ORDER
 #else
+#if !defined(__QNX__)
 #include <endian.h>  // __BYTE_ORDER
 #endif
+#endif
 #if ((defined(__LITTLE_ENDIAN__) && !defined(__BIG_ENDIAN__)) ||    \
      (defined(__BYTE_ORDER) && __BYTE_ORDER == __LITTLE_ENDIAN)) && \
     !defined(PROTOBUF_DISABLE_LITTLE_ENDIAN_OPT_FOR_TEST)
@@ -398,13 +400,6 @@
   // This is unrelated to PushLimit()/PopLimit().
   void SetTotalBytesLimit(int total_bytes_limit);
 
-  PROTOBUF_DEPRECATED_MSG(
-      "Please use the single parameter version of SetTotalBytesLimit(). The "
-      "second parameter is ignored.")
-  void SetTotalBytesLimit(int total_bytes_limit, int) {
-    SetTotalBytesLimit(total_bytes_limit);
-  }
-
   // The Total Bytes Limit minus the Current Position, or -1 if the total bytes
   // limit is INT_MAX.
   int BytesUntilTotalBytesLimit() const;
diff --git a/src/google/protobuf/io/coded_stream_unittest.cc b/src/google/protobuf/io/coded_stream_unittest.cc
index d02cc88..671bde9 100644
--- a/src/google/protobuf/io/coded_stream_unittest.cc
+++ b/src/google/protobuf/io/coded_stream_unittest.cc
@@ -741,7 +741,7 @@
 
   {
     CodedInputStream coded_input(&input);
-    coded_input.SetTotalBytesLimit(sizeof(kRawBytes), sizeof(kRawBytes));
+    coded_input.SetTotalBytesLimit(sizeof(kRawBytes));
     EXPECT_EQ(sizeof(kRawBytes), coded_input.BytesUntilTotalBytesLimit());
 
     std::string str;
@@ -864,7 +864,7 @@
 
   {
     CodedInputStream coded_input(&input);
-    coded_input.SetTotalBytesLimit(16, 16);
+    coded_input.SetTotalBytesLimit(16);
 
     std::string str;
     EXPECT_FALSE(coded_input.ReadString(&str, strlen(kRawBytes)));
@@ -886,7 +886,7 @@
   {
     CodedInputStream coded_input(&input);
     coded_input.PushLimit(sizeof(buffer_));
-    coded_input.SetTotalBytesLimit(16, 16);
+    coded_input.SetTotalBytesLimit(16);
 
     std::string str;
     EXPECT_FALSE(coded_input.ReadString(&str, strlen(kRawBytes)));
@@ -908,7 +908,7 @@
   {
     CodedInputStream coded_input(&input);
     coded_input.PushLimit(16);
-    coded_input.SetTotalBytesLimit(sizeof(buffer_), sizeof(buffer_));
+    coded_input.SetTotalBytesLimit(sizeof(buffer_));
     EXPECT_EQ(sizeof(buffer_), coded_input.BytesUntilTotalBytesLimit());
 
     std::string str;
@@ -1180,7 +1180,7 @@
 TEST_F(CodedStreamTest, TotalBytesLimit) {
   ArrayInputStream input(buffer_, sizeof(buffer_));
   CodedInputStream coded_input(&input);
-  coded_input.SetTotalBytesLimit(16, -1);
+  coded_input.SetTotalBytesLimit(16);
   EXPECT_EQ(16, coded_input.BytesUntilTotalBytesLimit());
 
   std::string str;
@@ -1200,7 +1200,7 @@
                       "A protocol message was rejected because it was too big",
                       errors[0]);
 
-  coded_input.SetTotalBytesLimit(32, -1);
+  coded_input.SetTotalBytesLimit(32);
   EXPECT_EQ(16, coded_input.BytesUntilTotalBytesLimit());
   EXPECT_TRUE(coded_input.ReadString(&str, 16));
   EXPECT_EQ(0, coded_input.BytesUntilTotalBytesLimit());
@@ -1213,7 +1213,7 @@
   CodedInputStream coded_input(&input);
 
   // Set both total_bytes_limit and a regular limit at 16 bytes.
-  coded_input.SetTotalBytesLimit(16, -1);
+  coded_input.SetTotalBytesLimit(16);
   CodedInputStream::Limit limit = coded_input.PushLimit(16);
 
   // Read 16 bytes.
diff --git a/src/google/protobuf/io/gzip_stream.h b/src/google/protobuf/io/gzip_stream.h
index 575a301..f0283e8 100644
--- a/src/google/protobuf/io/gzip_stream.h
+++ b/src/google/protobuf/io/gzip_stream.h
@@ -80,10 +80,10 @@
   inline int ZlibErrorCode() const { return zerror_; }
 
   // implements ZeroCopyInputStream ----------------------------------
-  bool Next(const void** data, int* size);
-  void BackUp(int count);
-  bool Skip(int count);
-  int64_t ByteCount() const;
+  bool Next(const void** data, int* size) override;
+  void BackUp(int count) override;
+  bool Skip(int count) override;
+  int64_t ByteCount() const override;
 
  private:
   Format format_;
@@ -167,9 +167,9 @@
   bool Close();
 
   // implements ZeroCopyOutputStream ---------------------------------
-  bool Next(void** data, int* size);
-  void BackUp(int count);
-  int64_t ByteCount() const;
+  bool Next(void** data, int* size) override;
+  void BackUp(int count) override;
+  int64_t ByteCount() const override;
 
  private:
   ZeroCopyOutputStream* sub_stream_;
diff --git a/src/google/protobuf/io/printer.h b/src/google/protobuf/io/printer.h
index 904b818..d4051e2 100644
--- a/src/google/protobuf/io/printer.h
+++ b/src/google/protobuf/io/printer.h
@@ -84,7 +84,7 @@
   // Override for AnnotationCollector::AddAnnotation.
   virtual void AddAnnotation(size_t begin_offset, size_t end_offset,
                              const std::string& file_path,
-                             const std::vector<int>& path) {
+                             const std::vector<int>& path) override {
     typename AnnotationProto::Annotation* annotation =
         annotation_proto_->add_annotation();
     for (int i = 0; i < path.size(); ++i) {
@@ -95,7 +95,7 @@
     annotation->set_end(end_offset);
   }
   // Override for AnnotationCollector::AddAnnotation.
-  virtual void AddAnnotationNew(Annotation& a) {
+  virtual void AddAnnotationNew(Annotation& a) override {
     auto* annotation = annotation_proto_->add_annotation();
     annotation->ParseFromString(a.second);
     annotation->set_begin(a.first.first);
diff --git a/src/google/protobuf/map_entry.h b/src/google/protobuf/map_entry.h
index e6822ac..2aec2d4 100644
--- a/src/google/protobuf/map_entry.h
+++ b/src/google/protobuf/map_entry.h
@@ -99,7 +99,7 @@
                      kValueFieldType>(arena),
         _internal_metadata_(arena) {}
   ~MapEntry() {
-    Message::_internal_metadata_.Delete<UnknownFieldSet>();
+    Message::_internal_metadata_.template Delete<UnknownFieldSet>();
     _internal_metadata_.Delete<UnknownFieldSet>();
   }
   typedef void InternalArenaConstructable_;
diff --git a/src/google/protobuf/map_entry_lite.h b/src/google/protobuf/map_entry_lite.h
index 03a388e..7dd50e2 100644
--- a/src/google/protobuf/map_entry_lite.h
+++ b/src/google/protobuf/map_entry_lite.h
@@ -528,7 +528,7 @@
       SuperType;
   constexpr MapEntryLite() {}
   explicit MapEntryLite(Arena* arena) : SuperType(arena) {}
-  ~MapEntryLite() { MessageLite::_internal_metadata_.Delete<std::string>(); }
+  ~MapEntryLite() { MessageLite::_internal_metadata_.template Delete<std::string>(); }
   void MergeFrom(const MapEntryLite& other) { MergeFromInternal(other); }
 
  private:
diff --git a/src/google/protobuf/map_test.inc b/src/google/protobuf/map_test.inc
index 44f4a81..4e8304f 100644
--- a/src/google/protobuf/map_test.inc
+++ b/src/google/protobuf/map_test.inc
@@ -30,7 +30,7 @@
 
 // A hack to include windows.h first, which ensures the GetMessage macro can
 // be undefined when we include <google/protobuf/stubs/common.h>
-#if defined(_WIN32)
+#if defined(_MSC_VER)
 #define _WINSOCKAPI_  // to avoid re-definition in WinSock2.h
 #define NOMINMAX      // to avoid defining min/max macros
 #include <windows.h>
diff --git a/src/google/protobuf/port_def.inc b/src/google/protobuf/port_def.inc
index 28c8b83..4834d9d 100644
--- a/src/google/protobuf/port_def.inc
+++ b/src/google/protobuf/port_def.inc
@@ -153,17 +153,17 @@
 #ifdef PROTOBUF_VERSION
 #error PROTOBUF_VERSION was previously defined
 #endif
-#define PROTOBUF_VERSION 3015008
+#define PROTOBUF_VERSION 3017003
 
 #ifdef PROTOBUF_MIN_HEADER_VERSION_FOR_PROTOC
 #error PROTOBUF_MIN_HEADER_VERSION_FOR_PROTOC was previously defined
 #endif
-#define PROTOBUF_MIN_HEADER_VERSION_FOR_PROTOC 3015000
+#define PROTOBUF_MIN_HEADER_VERSION_FOR_PROTOC 3017000
 
 #ifdef PROTOBUF_MIN_PROTOC_VERSION
 #error PROTOBUF_MIN_PROTOC_VERSION was previously defined
 #endif
-#define PROTOBUF_MIN_PROTOC_VERSION 3015000
+#define PROTOBUF_MIN_PROTOC_VERSION 3017000
 
 #ifdef PROTOBUF_VERSION_SUFFIX
 #error PROTOBUF_VERSION_SUFFIX was previously defined
@@ -350,7 +350,7 @@
 
 // The minimum library version which works with the current version of the
 // headers.
-#define GOOGLE_PROTOBUF_MIN_LIBRARY_VERSION 3015000
+#define GOOGLE_PROTOBUF_MIN_LIBRARY_VERSION 3017000
 
 #ifdef PROTOBUF_RTTI
 #error PROTOBUF_RTTI was previously defined
@@ -552,9 +552,10 @@
 #ifdef PROTOBUF_CONSTINIT
 #error PROTOBUF_CONSTINIT was previously defined
 #endif
-#if defined(__cpp_constinit) && !PROTOBUF_GNUC_MIN(3, 0)
+#if defined(__cpp_constinit) && !PROTOBUF_GNUC_MIN(3, 0) && !defined(_MSC_VER)
 // Our use of constinit does not yet work with GCC:
 // https://github.com/protocolbuffers/protobuf/issues/8310
+// Does not work yet with Visual Studio 2019 Update 16.10
 #define PROTOBUF_CONSTINIT constinit
 #elif __has_cpp_attribute(clang::require_constant_initialization)
 #define PROTOBUF_CONSTINIT [[clang::require_constant_initialization]]
@@ -584,7 +585,7 @@
 #ifdef PROTOBUF_ATTRIBUTE_INIT_PRIORITY
 #error PROTOBUF_ATTRIBUTE_INIT_PRIORITY was previously defined
 #endif
-#if PROTOBUF_GNUC_MIN(3, 0)
+#if PROTOBUF_GNUC_MIN(3, 0) && (!defined(__APPLE__) || defined(__clang__))
 #define PROTOBUF_ATTRIBUTE_INIT_PRIORITY __attribute__((init_priority((102))))
 #else
 #define PROTOBUF_ATTRIBUTE_INIT_PRIORITY
diff --git a/src/google/protobuf/reflection.h b/src/google/protobuf/reflection.h
index 6e4e647..00be9c0 100644
--- a/src/google/protobuf/reflection.h
+++ b/src/google/protobuf/reflection.h
@@ -392,13 +392,18 @@
 
 // Implement (Mutable)RepeatedFieldRef::iterator
 template <typename T>
-class RepeatedFieldRefIterator
-    : public std::iterator<std::forward_iterator_tag, T> {
+class RepeatedFieldRefIterator {
   typedef typename RefTypeTraits<T>::AccessorValueType AccessorValueType;
   typedef typename RefTypeTraits<T>::IteratorValueType IteratorValueType;
   typedef typename RefTypeTraits<T>::IteratorPointerType IteratorPointerType;
 
  public:
+  using iterator_category = std::forward_iterator_tag;
+  using value_type = T;
+  using pointer = T*;
+  using reference = T&;
+  using difference_type = std::ptrdiff_t;
+
   // Constructor for non-message fields.
   RepeatedFieldRefIterator(const void* data,
                            const RepeatedFieldAccessor* accessor, bool begin)
diff --git a/src/google/protobuf/repeated_field.h b/src/google/protobuf/repeated_field.h
index 4bf5a26..0541008 100644
--- a/src/google/protobuf/repeated_field.h
+++ b/src/google/protobuf/repeated_field.h
@@ -2736,9 +2736,14 @@
 namespace internal {
 // A back inserter for RepeatedField objects.
 template <typename T>
-class RepeatedFieldBackInsertIterator
-    : public std::iterator<std::output_iterator_tag, T> {
+class RepeatedFieldBackInsertIterator {
  public:
+  using iterator_category = std::output_iterator_tag;
+  using value_type = T;
+  using pointer = void;
+  using reference = void;
+  using difference_type = std::ptrdiff_t;
+
   explicit RepeatedFieldBackInsertIterator(
       RepeatedField<T>* const mutable_field)
       : field_(mutable_field) {}
@@ -2758,9 +2763,14 @@
 
 // A back inserter for RepeatedPtrField objects.
 template <typename T>
-class RepeatedPtrFieldBackInsertIterator
-    : public std::iterator<std::output_iterator_tag, T> {
+class RepeatedPtrFieldBackInsertIterator {
  public:
+  using iterator_category = std::output_iterator_tag;
+  using value_type = T;
+  using pointer = void;
+  using reference = void;
+  using difference_type = std::ptrdiff_t;
+
   RepeatedPtrFieldBackInsertIterator(RepeatedPtrField<T>* const mutable_field)
       : field_(mutable_field) {}
   RepeatedPtrFieldBackInsertIterator<T>& operator=(const T& value) {
@@ -2789,9 +2799,14 @@
 // A back inserter for RepeatedPtrFields that inserts by transferring ownership
 // of a pointer.
 template <typename T>
-class AllocatedRepeatedPtrFieldBackInsertIterator
-    : public std::iterator<std::output_iterator_tag, T> {
+class AllocatedRepeatedPtrFieldBackInsertIterator {
  public:
+  using iterator_category = std::output_iterator_tag;
+  using value_type = T;
+  using pointer = void;
+  using reference = void;
+  using difference_type = std::ptrdiff_t;
+
   explicit AllocatedRepeatedPtrFieldBackInsertIterator(
       RepeatedPtrField<T>* const mutable_field)
       : field_(mutable_field) {}
@@ -2813,9 +2828,14 @@
 // Almost identical to AllocatedRepeatedPtrFieldBackInsertIterator. This one
 // uses the UnsafeArenaAddAllocated instead.
 template <typename T>
-class UnsafeArenaAllocatedRepeatedPtrFieldBackInsertIterator
-    : public std::iterator<std::output_iterator_tag, T> {
+class UnsafeArenaAllocatedRepeatedPtrFieldBackInsertIterator {
  public:
+  using iterator_category = std::output_iterator_tag;
+  using value_type = T;
+  using pointer = void;
+  using reference = void;
+  using difference_type = std::ptrdiff_t;
+
   explicit UnsafeArenaAllocatedRepeatedPtrFieldBackInsertIterator(
       RepeatedPtrField<T>* const mutable_field)
       : field_(mutable_field) {}
diff --git a/src/google/protobuf/repeated_field_unittest.cc b/src/google/protobuf/repeated_field_unittest.cc
index ec00e86..429a63a 100644
--- a/src/google/protobuf/repeated_field_unittest.cc
+++ b/src/google/protobuf/repeated_field_unittest.cc
@@ -889,8 +889,8 @@
 
   // Construction from string iterators for the unique string overload "g"
   // works.
-  // std::string b[2] = {"abc", "xyz"};
   // Disabling this for now, this is actually ambiguous with libstdc++.
+  // std::string b[2] = {"abc", "xyz"};
   // EXPECT_TRUE(X::g({b, b + 2}));
 
   // Construction from string iterators for "f" is ambiguous, since both
diff --git a/src/google/protobuf/source_context.pb.cc b/src/google/protobuf/source_context.pb.cc
index 188ed25..14620c3 100644
--- a/src/google/protobuf/source_context.pb.cc
+++ b/src/google/protobuf/source_context.pb.cc
@@ -100,7 +100,7 @@
   // @@protoc_insertion_point(copy_constructor:google.protobuf.SourceContext)
 }
 
-inline void SourceContext::SharedCtor() {
+void SourceContext::SharedCtor() {
 file_name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
 }
 
diff --git a/src/google/protobuf/source_context.pb.h b/src/google/protobuf/source_context.pb.h
index 566e5bf..26e665b 100644
--- a/src/google/protobuf/source_context.pb.h
+++ b/src/google/protobuf/source_context.pb.h
@@ -8,12 +8,12 @@
 #include <string>
 
 #include <google/protobuf/port_def.inc>
-#if PROTOBUF_VERSION < 3015000
+#if PROTOBUF_VERSION < 3017000
 #error This file was generated by a newer version of protoc which is
 #error incompatible with your Protocol Buffer headers. Please update
 #error your headers.
 #endif
-#if 3015008 < PROTOBUF_MIN_PROTOC_VERSION
+#if 3017003 < 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.
@@ -52,7 +52,7 @@
   static const ::PROTOBUF_NAMESPACE_ID::internal::SerializationTable serialization_table[];
   static const ::PROTOBUF_NAMESPACE_ID::uint32 offsets[];
 };
-extern PROTOBUF_EXPORT const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable descriptor_table_google_2fprotobuf_2fsource_5fcontext_2eproto;
+PROTOBUF_EXPORT extern const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable descriptor_table_google_2fprotobuf_2fsource_5fcontext_2eproto;
 PROTOBUF_NAMESPACE_OPEN
 class SourceContext;
 struct SourceContextDefaultTypeInternal;
diff --git a/src/google/protobuf/struct.pb.cc b/src/google/protobuf/struct.pb.cc
index 9f2c843..766d99e 100644
--- a/src/google/protobuf/struct.pb.cc
+++ b/src/google/protobuf/struct.pb.cc
@@ -205,7 +205,7 @@
   // @@protoc_insertion_point(copy_constructor:google.protobuf.Struct)
 }
 
-inline void Struct::SharedCtor() {
+void Struct::SharedCtor() {
 }
 
 Struct::~Struct() {
@@ -498,7 +498,7 @@
   // @@protoc_insertion_point(copy_constructor:google.protobuf.Value)
 }
 
-inline void Value::SharedCtor() {
+void Value::SharedCtor() {
 clear_has_kind();
 }
 
@@ -865,7 +865,7 @@
   // @@protoc_insertion_point(copy_constructor:google.protobuf.ListValue)
 }
 
-inline void ListValue::SharedCtor() {
+void ListValue::SharedCtor() {
 }
 
 ListValue::~ListValue() {
diff --git a/src/google/protobuf/struct.pb.h b/src/google/protobuf/struct.pb.h
index dc00ec5..2d364f9 100644
--- a/src/google/protobuf/struct.pb.h
+++ b/src/google/protobuf/struct.pb.h
@@ -8,12 +8,12 @@
 #include <string>
 
 #include <google/protobuf/port_def.inc>
-#if PROTOBUF_VERSION < 3015000
+#if PROTOBUF_VERSION < 3017000
 #error This file was generated by a newer version of protoc which is
 #error incompatible with your Protocol Buffer headers. Please update
 #error your headers.
 #endif
-#if 3015008 < PROTOBUF_MIN_PROTOC_VERSION
+#if 3017003 < 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.
@@ -56,7 +56,7 @@
   static const ::PROTOBUF_NAMESPACE_ID::internal::SerializationTable serialization_table[];
   static const ::PROTOBUF_NAMESPACE_ID::uint32 offsets[];
 };
-extern PROTOBUF_EXPORT const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable descriptor_table_google_2fprotobuf_2fstruct_2eproto;
+PROTOBUF_EXPORT extern const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable descriptor_table_google_2fprotobuf_2fstruct_2eproto;
 PROTOBUF_NAMESPACE_OPEN
 class ListValue;
 struct ListValueDefaultTypeInternal;
diff --git a/src/google/protobuf/stubs/common.h b/src/google/protobuf/stubs/common.h
index 050497f..23125bf 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 3015008
+#define GOOGLE_PROTOBUF_VERSION 3017003
 
 // A suffix string for alpha, beta or rc releases. Empty for stable releases.
 #define GOOGLE_PROTOBUF_VERSION_SUFFIX ""
@@ -90,15 +90,15 @@
 // The minimum header version which works with the current version of
 // the library.  This constant should only be used by protoc's C++ code
 // generator.
-static const int kMinHeaderVersionForLibrary = 3015000;
+static const int kMinHeaderVersionForLibrary = 3017000;
 
 // The minimum protoc version which works with the current version of the
 // headers.
-#define GOOGLE_PROTOBUF_MIN_PROTOC_VERSION 3015000
+#define GOOGLE_PROTOBUF_MIN_PROTOC_VERSION 3017000
 
 // The minimum header version which works with the current version of
 // protoc.  This constant should only be used in VerifyVersion().
-static const int kMinHeaderVersionForProtoc = 3015000;
+static const int kMinHeaderVersionForProtoc = 3017000;
 
 // Verifies that the headers and libraries are compatible.  Use the macro
 // below to call this.
@@ -176,7 +176,7 @@
       : filename_(filename), line_(line), message_(message) {}
   virtual ~FatalException() throw();
 
-  virtual const char* what() const throw();
+  virtual const char* what() const throw() override;
 
   const char* filename() const { return filename_; }
   int line() const { return line_; }
diff --git a/src/google/protobuf/stubs/mutex.h b/src/google/protobuf/stubs/mutex.h
index bff9681..5c025b1 100644
--- a/src/google/protobuf/stubs/mutex.h
+++ b/src/google/protobuf/stubs/mutex.h
@@ -52,10 +52,12 @@
   __attribute__((acquire_capability(__VA_ARGS__)))
 #define GOOGLE_PROTOBUF_RELEASE(...) \
   __attribute__((release_capability(__VA_ARGS__)))
+#define GOOGLE_PROTOBUF_SCOPED_CAPABILITY __attribute__((scoped_lockable))
 #define GOOGLE_PROTOBUF_CAPABILITY(x) __attribute__((capability(x)))
 #else
 #define GOOGLE_PROTOBUF_ACQUIRE(...)
 #define GOOGLE_PROTOBUF_RELEASE(...)
+#define GOOGLE_PROTOBUF_SCOPED_CAPABILITY
 #define GOOGLE_PROTOBUF_CAPABILITY(x)
 #endif
 
@@ -116,7 +118,11 @@
 // mutexes.
 class GOOGLE_PROTOBUF_CAPABILITY("mutex") PROTOBUF_EXPORT WrappedMutex {
  public:
+#if defined(__QNX__)
+  constexpr WrappedMutex() = default;
+#else
   constexpr WrappedMutex() {}
+#endif
   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.
@@ -136,10 +142,12 @@
 using Mutex = WrappedMutex;
 
 // MutexLock(mu) acquires mu when constructed and releases it when destroyed.
-class PROTOBUF_EXPORT MutexLock {
+class GOOGLE_PROTOBUF_SCOPED_CAPABILITY PROTOBUF_EXPORT MutexLock {
  public:
-  explicit MutexLock(Mutex *mu) : mu_(mu) { this->mu_->Lock(); }
-  ~MutexLock() { this->mu_->Unlock(); }
+  explicit MutexLock(Mutex *mu) GOOGLE_PROTOBUF_ACQUIRE(mu) : mu_(mu) {
+    this->mu_->Lock();
+  }
+  ~MutexLock() GOOGLE_PROTOBUF_RELEASE() { this->mu_->Unlock(); }
  private:
   Mutex *const mu_;
   GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MutexLock);
diff --git a/src/google/protobuf/stubs/platform_macros.h b/src/google/protobuf/stubs/platform_macros.h
index ce1b1e3..2479960 100644
--- a/src/google/protobuf/stubs/platform_macros.h
+++ b/src/google/protobuf/stubs/platform_macros.h
@@ -46,7 +46,11 @@
 #define GOOGLE_PROTOBUF_ARCH_32_BIT 1
 #elif defined(__QNX__)
 #define GOOGLE_PROTOBUF_ARCH_ARM_QNX 1
+#if defined(__aarch64__)
+#define GOOGLE_PROTOBUF_ARCH_64_BIT 1
+#else
 #define GOOGLE_PROTOBUF_ARCH_32_BIT 1
+#endif
 #elif defined(_M_ARM) || defined(__ARMEL__)
 #define GOOGLE_PROTOBUF_ARCH_ARM 1
 #define GOOGLE_PROTOBUF_ARCH_32_BIT 1
diff --git a/src/google/protobuf/stubs/port.h b/src/google/protobuf/stubs/port.h
index eec96fa..d4d2736 100644
--- a/src/google/protobuf/stubs/port.h
+++ b/src/google/protobuf/stubs/port.h
@@ -62,8 +62,10 @@
 #elif defined(__FreeBSD__)
 #include <sys/endian.h>  // __BYTE_ORDER
 #else
+#if !defined(__QNX__)
 #include <endian.h>  // __BYTE_ORDER
 #endif
+#endif
 #if ((defined(__LITTLE_ENDIAN__) && !defined(__BIG_ENDIAN__)) ||   \
      (defined(__BYTE_ORDER) && __BYTE_ORDER == __LITTLE_ENDIAN) || \
      (defined(BYTE_ORDER) && BYTE_ORDER == LITTLE_ENDIAN)) &&      \
@@ -263,14 +265,14 @@
 
 #ifndef bswap_64
 static inline uint64 bswap_64(uint64 x) {
-  return (((x & uint64_t{0xFFu)) << 56) |
-          ((x & uint64_t{0xFF00u)) << 40) |
-          ((x & uint64_t{0xFF0000u)) << 24) |
-          ((x & uint64_t{0xFF000000u)) << 8) |
-          ((x & uint64_t{0xFF00000000u)) >> 8) |
-          ((x & uint64_t{0xFF0000000000u)) >> 24) |
-          ((x & uint64_t{0xFF000000000000u)) >> 40) |
-          ((x & uint64_t{0xFF00000000000000u)) >> 56));
+  return (((x & uint64_t{0xFFu}) << 56) |
+          ((x & uint64_t{0xFF00u}) << 40) |
+          ((x & uint64_t{0xFF0000u}) << 24) |
+          ((x & uint64_t{0xFF000000u}) << 8) |
+          ((x & uint64_t{0xFF00000000u}) >> 8) |
+          ((x & uint64_t{0xFF0000000000u}) >> 24) |
+          ((x & uint64_t{0xFF000000000000u}) >> 40) |
+          ((x & uint64_t{0xFF00000000000000u}) >> 56));
 }
 #define bswap_64(x) bswap_64(x)
 #endif
diff --git a/src/google/protobuf/stubs/stringpiece.h b/src/google/protobuf/stubs/stringpiece.h
index e6f5c71..c63e25b 100644
--- a/src/google/protobuf/stubs/stringpiece.h
+++ b/src/google/protobuf/stubs/stringpiece.h
@@ -148,6 +148,10 @@
 #include <limits>
 #include <string>
 
+#if defined(__cpp_lib_string_view)
+#include <string_view>
+#endif
+
 #include <google/protobuf/stubs/hash.h>
 
 #include <google/protobuf/port_def.inc>
@@ -215,6 +219,14 @@
     length_ = CheckSize(str.size());
   }
 
+#if defined(__cpp_lib_string_view)
+  StringPiece(  // NOLINT(runtime/explicit)
+      std::string_view str)
+      : ptr_(str.data()), length_(0) {
+    length_ = CheckSize(str.size());
+  }
+#endif
+
   StringPiece(const char* offset, size_type len)
       : ptr_(offset), length_(CheckSize(len)) {}
 
diff --git a/src/google/protobuf/stubs/stringprintf_unittest.cc b/src/google/protobuf/stubs/stringprintf_unittest.cc
index 37172a9..63f38bf 100644
--- a/src/google/protobuf/stubs/stringprintf_unittest.cc
+++ b/src/google/protobuf/stubs/stringprintf_unittest.cc
@@ -32,6 +32,7 @@
 
 #include <google/protobuf/stubs/stringprintf.h>
 
+#include <array>
 #include <cerrno>
 #include <string>
 
@@ -91,7 +92,9 @@
   // out of memory while trying to determine destination buffer size.
   // see b/4194543.
 
-  char* old_locale = setlocale(LC_CTYPE, nullptr);
+  char* old_locale_c = setlocale(LC_CTYPE, nullptr);
+  ASSERT_TRUE(old_locale_c != nullptr);
+  std::string old_locale = old_locale_c;
   // Push locale with multibyte mode
   setlocale(LC_CTYPE, "en_US.utf8");
 
@@ -106,24 +109,25 @@
 
   // Repeat with longer string, to make sure that the dynamically
   // allocated path in StringAppendV is handled correctly.
-  int n = 2048;
-  char* buf = new char[n+1];
-  memset(buf, ' ', n-3);
-  memcpy(buf + n - 3, kInvalidCodePoint, 4);
-  value =  StringPrintf("%.*s", n, buf);
+  const size_t n = 2048;
+  std::array<char, n+1> buf;
+  memset(&buf[0], ' ', n-3);
+  memcpy(&buf[0] + n - 3, kInvalidCodePoint, 4);
+  value =  StringPrintf("%.*s", n, &buf[0]);
   // See GRTEv2 vs. GRTEv3 comment above.
-  EXPECT_TRUE(value.empty() || value == buf);
-  delete[] buf;
+  EXPECT_TRUE(value.empty() || value == &buf[0]);
 
-  setlocale(LC_CTYPE, old_locale);
+  setlocale(LC_CTYPE, old_locale.c_str());
 }
 
 TEST(StringPrintfTest, NoMultibyte) {
   // No multibyte handling, but the string contains funny chars.
-  char* old_locale = setlocale(LC_CTYPE, nullptr);
+  char* old_locale_c = setlocale(LC_CTYPE, nullptr);
+  ASSERT_TRUE(old_locale_c != nullptr);
+  std::string old_locale = old_locale_c;
   setlocale(LC_CTYPE, "POSIX");
   std::string value = StringPrintf("%.*s", 3, "\375\067s");
-  setlocale(LC_CTYPE, old_locale);
+  setlocale(LC_CTYPE, old_locale.c_str());
   EXPECT_EQ("\375\067s", value);
 }
 
diff --git a/src/google/protobuf/stubs/strutil.cc b/src/google/protobuf/stubs/strutil.cc
index bbc581e..0865f9f 100644
--- a/src/google/protobuf/stubs/strutil.cc
+++ b/src/google/protobuf/stubs/strutil.cc
@@ -1287,7 +1287,7 @@
   const unsigned char *us1 = reinterpret_cast<const unsigned char *>(s1);
   const unsigned char *us2 = reinterpret_cast<const unsigned char *>(s2);
 
-  for ( int i = 0; i < len; i++ ) {
+  for (size_t i = 0; i < len; i++) {
     const int diff =
       static_cast<int>(static_cast<unsigned char>(ascii_tolower(us1[i]))) -
       static_cast<int>(static_cast<unsigned char>(ascii_tolower(us2[i])));
@@ -2101,7 +2101,7 @@
   char *limit_dest = dest + szdest;
   const unsigned char *limit_src = src + szsrc;
 
-  // Three bytes of data encodes to four characters of cyphertext.
+  // Three bytes of data encodes to four characters of ciphertext.
   // So we can pump through three-byte chunks atomically.
   while (cur_src < limit_src - 3) {  // keep going as long as we have >= 32 bits
     uint32 in = BigEndian::Load32(cur_src) >> 8;
@@ -2128,7 +2128,7 @@
       break;
     case 1: {
       // One byte left: this encodes to two characters, and (optionally)
-      // two pad characters to round out the four-character cypherblock.
+      // two pad characters to round out the four-character cipherblock.
       if ((szdest -= 2) < 0) return 0;
       uint32 in = cur_src[0];
       cur_dest[0] = base64[in >> 2];
@@ -2145,7 +2145,7 @@
     }
     case 2: {
       // Two bytes left: this encodes to three characters, and (optionally)
-      // one pad character to round out the four-character cypherblock.
+      // one pad character to round out the four-character cipherblock.
       if ((szdest -= 3) < 0) return 0;
       uint32 in = BigEndian::Load16(cur_src);
       cur_dest[0] = base64[in >> 10];
diff --git a/src/google/protobuf/stubs/strutil_unittest.cc b/src/google/protobuf/stubs/strutil_unittest.cc
index fc9a63f..0fbfab4 100644
--- a/src/google/protobuf/stubs/strutil_unittest.cc
+++ b/src/google/protobuf/stubs/strutil_unittest.cc
@@ -83,7 +83,7 @@
 static struct {
   int plain_length;
   const char* plaintext;
-  const char* cyphertext;
+  const char* ciphertext;
 } base64_tests[] = {
   // Empty string.
   { 0, "", ""},
@@ -343,10 +343,10 @@
 
 static struct {
   const char* plaintext;
-  const char* cyphertext;
+  const char* ciphertext;
 } base64_strings[] = {
   // Some google quotes
-  // Cyphertext created with "uuencode (GNU sharutils) 4.6.3"
+  // Ciphertext created with "uuencode (GNU sharutils) 4.6.3"
   // (Note that we're testing the websafe encoding, though, so if
   // you add messages, be sure to run "tr -- '+/' '-_'" on the output)
   { "I was always good at math and science, and I never realized "
@@ -441,7 +441,7 @@
     int encode_length;
     char decode_buffer[100];
     int decode_length;
-    int cypher_length;
+    int cipher_length;
     std::string decode_str;
 
     const unsigned char* unsigned_plaintext =
@@ -450,7 +450,7 @@
     StringPiece plaintext(base64_tests[i].plaintext,
                           base64_tests[i].plain_length);
 
-    cypher_length = strlen(base64_tests[i].cyphertext);
+    cipher_length = strlen(base64_tests[i].ciphertext);
 
     // The basic escape function:
     memset(encode_buffer, 0, sizeof(encode_buffer));
@@ -459,30 +459,30 @@
                                  encode_buffer,
                                  sizeof(encode_buffer));
     //    Is it of the expected length?
-    EXPECT_EQ(encode_length, cypher_length);
+    EXPECT_EQ(encode_length, cipher_length);
     // Would it have been okay to allocate only CalculateBase64EscapeLen()?
     EXPECT_EQ(CalculateBase64EscapedLen(base64_tests[i].plain_length),
               encode_length);
 
     //    Is it the expected encoded value?
-    ASSERT_STREQ(encode_buffer, base64_tests[i].cyphertext);
+    ASSERT_STREQ(encode_buffer, base64_tests[i].ciphertext);
 
     // If we encode it into a buffer of exactly the right length...
     memset(encode_buffer, 0, sizeof(encode_buffer));
     encode_length = Base64Escape(unsigned_plaintext,
                                           base64_tests[i].plain_length,
                                           encode_buffer,
-                                          cypher_length);
+                                          cipher_length);
     //    Is it still of the expected length?
-    EXPECT_EQ(encode_length, cypher_length);
+    EXPECT_EQ(encode_length, cipher_length);
 
     //    And is the value still correct?  (i.e., not losing the last byte)
-    EXPECT_STREQ(encode_buffer, base64_tests[i].cyphertext);
+    EXPECT_STREQ(encode_buffer, base64_tests[i].ciphertext);
 
     // If we decode it back:
     decode_str.clear();
     EXPECT_TRUE(Base64Unescape(
-        StringPiece(encode_buffer, cypher_length), &decode_str));
+        StringPiece(encode_buffer, cipher_length), &decode_str));
 
     //    Is it of the expected length?
     EXPECT_EQ(base64_tests[i].plain_length, decode_str.length());
@@ -495,11 +495,11 @@
     Base64Escape(
         std::string(base64_tests[i].plaintext, base64_tests[i].plain_length),
         &encoded);
-    EXPECT_EQ(encoded, std::string(encode_buffer, cypher_length));
+    EXPECT_EQ(encoded, std::string(encode_buffer, cipher_length));
 
     std::string decoded("this junk should be ignored");
     EXPECT_TRUE(Base64Unescape(
-        StringPiece(encode_buffer, cypher_length), &decoded));
+        StringPiece(encode_buffer, cipher_length), &decoded));
     EXPECT_EQ(decoded.size(), base64_tests[i].plain_length);
     EXPECT_EQ_ARRAY(decoded.size(), decoded, base64_tests[i].plaintext, i);
 
@@ -578,7 +578,7 @@
 
     char websafe[100];
     memset(websafe, 0, sizeof(websafe));
-    strncpy(websafe, base64_tests[i].cyphertext, cypher_length);
+    strncpy(websafe, base64_tests[i].ciphertext, cipher_length);
     for (int c = 0; c < sizeof(websafe); ++c) {
       if ('+' == websafe[c]) { websafe[c] = '-'; }
       if ('/' == websafe[c]) { websafe[c] = '_'; }
@@ -592,7 +592,7 @@
                                                  sizeof(encode_buffer),
                                                  true);
     //    Is it of the expected length?
-    EXPECT_EQ(encode_length, cypher_length);
+    EXPECT_EQ(encode_length, cipher_length);
     EXPECT_EQ(
         CalculateBase64EscapedLen(base64_tests[i].plain_length, true),
         encode_length);
@@ -605,10 +605,10 @@
     encode_length = WebSafeBase64Escape(unsigned_plaintext,
                                                  base64_tests[i].plain_length,
                                                  encode_buffer,
-                                                 cypher_length,
+                                                 cipher_length,
                                                  true);
     //    Is it still of the expected length?
-    EXPECT_EQ(encode_length, cypher_length);
+    EXPECT_EQ(encode_length, cipher_length);
 
     //    And is the value still correct?  (i.e., not losing the last byte)
     EXPECT_STREQ(encode_buffer, websafe);
@@ -618,13 +618,13 @@
     WebSafeBase64Escape(
         unsigned_plaintext, base64_tests[i].plain_length,
         &encoded, true);
-    EXPECT_EQ(encoded.size(), cypher_length);
+    EXPECT_EQ(encoded.size(), cipher_length);
     EXPECT_STREQ(encoded.c_str(), websafe);
 
     //    If we decode it back:
     memset(decode_buffer, 0, sizeof(decode_buffer));
     decode_length = WebSafeBase64Unescape(encode_buffer,
-                                                   cypher_length,
+                                                   cipher_length,
                                                    decode_buffer,
                                                    sizeof(decode_buffer));
 
@@ -638,7 +638,7 @@
     //    If we decode it into a buffer of exactly the right length...
     memset(decode_buffer, 0, sizeof(decode_buffer));
     decode_length = WebSafeBase64Unescape(encode_buffer,
-                                                   cypher_length,
+                                                   cipher_length,
                                                    decode_buffer,
                                                    decode_length);
 
@@ -650,14 +650,14 @@
               memcmp(decode_buffer, base64_tests[i].plaintext, decode_length));
 
     // Try using '.' for the pad character.
-    for (int c = cypher_length - 1; c >= 0 && '=' == encode_buffer[c]; --c) {
+    for (int c = cipher_length - 1; c >= 0 && '=' == encode_buffer[c]; --c) {
       encode_buffer[c] = '.';
     }
 
     // If we decode it back:
     memset(decode_buffer, 0, sizeof(decode_buffer));
     decode_length = WebSafeBase64Unescape(encode_buffer,
-                                                   cypher_length,
+                                                   cipher_length,
                                                    decode_buffer,
                                                    sizeof(decode_buffer));
 
@@ -671,7 +671,7 @@
     // If we decode it into a buffer of exactly the right length...
     memset(decode_buffer, 0, sizeof(decode_buffer));
     decode_length = WebSafeBase64Unescape(encode_buffer,
-                                                   cypher_length,
+                                                   cipher_length,
                                                    decode_buffer,
                                                    decode_length);
 
@@ -685,7 +685,7 @@
     // Let's try the string version of the decoder
     decoded = "this junk should be ignored";
     EXPECT_TRUE(WebSafeBase64Unescape(
-        StringPiece(encode_buffer, cypher_length), &decoded));
+        StringPiece(encode_buffer, cipher_length), &decoded));
     EXPECT_EQ(decoded.size(), base64_tests[i].plain_length);
     EXPECT_EQ_ARRAY(decoded.size(), decoded, base64_tests[i].plaintext, i);
 
@@ -695,7 +695,7 @@
     for (int c = 0; c < sizeof(websafe); ++c) {
       if ('=' == websafe[c]) {
         websafe[c] = '\0';
-        cypher_length = c;
+        cipher_length = c;
         break;
       }
     }
@@ -708,7 +708,7 @@
                                                  sizeof(encode_buffer),
                                                  false);
     //    Is it of the expected length?
-    EXPECT_EQ(encode_length, cypher_length);
+    EXPECT_EQ(encode_length, cipher_length);
     EXPECT_EQ(
         CalculateBase64EscapedLen(base64_tests[i].plain_length, false),
         encode_length);
@@ -721,10 +721,10 @@
     encode_length = WebSafeBase64Escape(unsigned_plaintext,
                                                  base64_tests[i].plain_length,
                                                  encode_buffer,
-                                                 cypher_length,
+                                                 cipher_length,
                                                  false);
     //    Is it still of the expected length?
-    EXPECT_EQ(encode_length, cypher_length);
+    EXPECT_EQ(encode_length, cipher_length);
 
     //    And is the value still correct?  (i.e., not losing the last byte)
     EXPECT_STREQ(encode_buffer, websafe);
@@ -733,13 +733,13 @@
     std::string plain(base64_tests[i].plaintext, base64_tests[i].plain_length);
     encoded = "this junk should be ignored";
     WebSafeBase64Escape(plain, &encoded);
-    EXPECT_EQ(encoded.size(), cypher_length);
+    EXPECT_EQ(encoded.size(), cipher_length);
     EXPECT_STREQ(encoded.c_str(), websafe);
 
     //    If we decode it back:
     memset(decode_buffer, 0, sizeof(decode_buffer));
     decode_length = WebSafeBase64Unescape(encode_buffer,
-                                                   cypher_length,
+                                                   cipher_length,
                                                    decode_buffer,
                                                    sizeof(decode_buffer));
 
@@ -753,7 +753,7 @@
     //    If we decode it into a buffer of exactly the right length...
     memset(decode_buffer, 0, sizeof(decode_buffer));
     decode_length = WebSafeBase64Unescape(encode_buffer,
-                                                   cypher_length,
+                                                   cipher_length,
                                                    decode_buffer,
                                                    decode_length);
 
@@ -768,7 +768,7 @@
     // Let's try the string version of the decoder
     decoded = "this junk should be ignored";
     EXPECT_TRUE(WebSafeBase64Unescape(
-        StringPiece(encode_buffer, cypher_length), &decoded));
+        StringPiece(encode_buffer, cipher_length), &decoded));
     EXPECT_EQ(decoded.size(), base64_tests[i].plain_length);
     EXPECT_EQ_ARRAY(decoded.size(), decoded, base64_tests[i].plaintext, i);
 
@@ -781,18 +781,18 @@
     const unsigned char* unsigned_plaintext =
       reinterpret_cast<const unsigned char*>(base64_strings[i].plaintext);
     int plain_length = strlen(base64_strings[i].plaintext);
-    int cypher_length = strlen(base64_strings[i].cyphertext);
-    std::vector<char> buffer(cypher_length+1);
+    int cipher_length = strlen(base64_strings[i].ciphertext);
+    std::vector<char> buffer(cipher_length+1);
     int encode_length = WebSafeBase64Escape(unsigned_plaintext,
                                                      plain_length,
                                                      &buffer[0],
                                                      buffer.size(),
                                                      false);
-    EXPECT_EQ(cypher_length, encode_length);
+    EXPECT_EQ(cipher_length, encode_length);
     EXPECT_EQ(
         CalculateBase64EscapedLen(plain_length, false), encode_length);
     buffer[ encode_length ] = '\0';
-    EXPECT_STREQ(base64_strings[i].cyphertext, &buffer[0]);
+    EXPECT_STREQ(base64_strings[i].ciphertext, &buffer[0]);
   }
 
   // Verify the behavior when decoding bad data
diff --git a/src/google/protobuf/timestamp.pb.cc b/src/google/protobuf/timestamp.pb.cc
index 61f0bf8..43954d9 100644
--- a/src/google/protobuf/timestamp.pb.cc
+++ b/src/google/protobuf/timestamp.pb.cc
@@ -100,7 +100,7 @@
   // @@protoc_insertion_point(copy_constructor:google.protobuf.Timestamp)
 }
 
-inline void Timestamp::SharedCtor() {
+void Timestamp::SharedCtor() {
 ::memset(reinterpret_cast<char*>(this) + static_cast<size_t>(
     reinterpret_cast<char*>(&seconds_) - reinterpret_cast<char*>(this)),
     0, static_cast<size_t>(reinterpret_cast<char*>(&nanos_) -
diff --git a/src/google/protobuf/timestamp.pb.h b/src/google/protobuf/timestamp.pb.h
index 23a0669..3efba58 100644
--- a/src/google/protobuf/timestamp.pb.h
+++ b/src/google/protobuf/timestamp.pb.h
@@ -8,12 +8,12 @@
 #include <string>
 
 #include <google/protobuf/port_def.inc>
-#if PROTOBUF_VERSION < 3015000
+#if PROTOBUF_VERSION < 3017000
 #error This file was generated by a newer version of protoc which is
 #error incompatible with your Protocol Buffer headers. Please update
 #error your headers.
 #endif
-#if 3015008 < PROTOBUF_MIN_PROTOC_VERSION
+#if 3017003 < 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.
@@ -52,7 +52,7 @@
   static const ::PROTOBUF_NAMESPACE_ID::internal::SerializationTable serialization_table[];
   static const ::PROTOBUF_NAMESPACE_ID::uint32 offsets[];
 };
-extern PROTOBUF_EXPORT const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable descriptor_table_google_2fprotobuf_2ftimestamp_2eproto;
+PROTOBUF_EXPORT extern const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable descriptor_table_google_2fprotobuf_2ftimestamp_2eproto;
 PROTOBUF_NAMESPACE_OPEN
 class Timestamp;
 struct TimestampDefaultTypeInternal;
diff --git a/src/google/protobuf/type.pb.cc b/src/google/protobuf/type.pb.cc
index 8b2e12a..c892956 100644
--- a/src/google/protobuf/type.pb.cc
+++ b/src/google/protobuf/type.pb.cc
@@ -385,7 +385,7 @@
   // @@protoc_insertion_point(copy_constructor:google.protobuf.Type)
 }
 
-inline void Type::SharedCtor() {
+void Type::SharedCtor() {
 name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
 ::memset(reinterpret_cast<char*>(this) + static_cast<size_t>(
     reinterpret_cast<char*>(&source_context_) - reinterpret_cast<char*>(this)),
@@ -767,7 +767,7 @@
   // @@protoc_insertion_point(copy_constructor:google.protobuf.Field)
 }
 
-inline void Field::SharedCtor() {
+void Field::SharedCtor() {
 name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
 type_url_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
 json_name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
@@ -1259,7 +1259,7 @@
   // @@protoc_insertion_point(copy_constructor:google.protobuf.Enum)
 }
 
-inline void Enum::SharedCtor() {
+void Enum::SharedCtor() {
 name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
 ::memset(reinterpret_cast<char*>(this) + static_cast<size_t>(
     reinterpret_cast<char*>(&source_context_) - reinterpret_cast<char*>(this)),
@@ -1588,7 +1588,7 @@
   // @@protoc_insertion_point(copy_constructor:google.protobuf.EnumValue)
 }
 
-inline void EnumValue::SharedCtor() {
+void EnumValue::SharedCtor() {
 name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
 number_ = 0;
 }
@@ -1857,7 +1857,7 @@
   // @@protoc_insertion_point(copy_constructor:google.protobuf.Option)
 }
 
-inline void Option::SharedCtor() {
+void Option::SharedCtor() {
 name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
 value_ = nullptr;
 }
diff --git a/src/google/protobuf/type.pb.h b/src/google/protobuf/type.pb.h
index 02749d8..ca45f0f 100644
--- a/src/google/protobuf/type.pb.h
+++ b/src/google/protobuf/type.pb.h
@@ -8,12 +8,12 @@
 #include <string>
 
 #include <google/protobuf/port_def.inc>
-#if PROTOBUF_VERSION < 3015000
+#if PROTOBUF_VERSION < 3017000
 #error This file was generated by a newer version of protoc which is
 #error incompatible with your Protocol Buffer headers. Please update
 #error your headers.
 #endif
-#if 3015008 < PROTOBUF_MIN_PROTOC_VERSION
+#if 3017003 < 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.
@@ -55,7 +55,7 @@
   static const ::PROTOBUF_NAMESPACE_ID::internal::SerializationTable serialization_table[];
   static const ::PROTOBUF_NAMESPACE_ID::uint32 offsets[];
 };
-extern PROTOBUF_EXPORT const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable descriptor_table_google_2fprotobuf_2ftype_2eproto;
+PROTOBUF_EXPORT extern const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable descriptor_table_google_2fprotobuf_2ftype_2eproto;
 PROTOBUF_NAMESPACE_OPEN
 class Enum;
 struct EnumDefaultTypeInternal;
diff --git a/src/google/protobuf/util/field_mask_util.cc b/src/google/protobuf/util/field_mask_util.cc
index c5f713f..646f807 100644
--- a/src/google/protobuf/util/field_mask_util.cc
+++ b/src/google/protobuf/util/field_mask_util.cc
@@ -52,9 +52,9 @@
 void FieldMaskUtil::FromString(StringPiece str, FieldMask* out) {
   out->Clear();
   std::vector<std::string> paths = Split(str, ",");
-  for (int i = 0; i < paths.size(); ++i) {
-    if (paths[i].empty()) continue;
-    out->add_paths(paths[i]);
+  for (const std::string& path : paths) {
+    if (path.empty()) continue;
+    out->add_paths(path);
   }
 }
 
@@ -62,23 +62,23 @@
                                          std::string* output) {
   output->clear();
   bool after_underscore = false;
-  for (int i = 0; i < input.size(); ++i) {
-    if (input[i] >= 'A' && input[i] <= 'Z') {
+  for (const char& input_char : input) {
+    if (input_char >= 'A' && input_char <= 'Z') {
       // The field name must not contain uppercase letters.
       return false;
     }
     if (after_underscore) {
-      if (input[i] >= 'a' && input[i] <= 'z') {
-        output->push_back(input[i] + 'A' - 'a');
+      if (input_char >= 'a' && input_char <= 'z') {
+        output->push_back(input_char + 'A' - 'a');
         after_underscore = false;
       } else {
         // The character after a "_" must be a lowercase letter.
         return false;
       }
-    } else if (input[i] == '_') {
+    } else if (input_char == '_') {
       after_underscore = true;
     } else {
-      output->push_back(input[i]);
+      output->push_back(input_char);
     }
   }
   if (after_underscore) {
@@ -91,16 +91,16 @@
 bool FieldMaskUtil::CamelCaseToSnakeCase(StringPiece input,
                                          std::string* output) {
   output->clear();
-  for (int i = 0; i < input.size(); ++i) {
-    if (input[i] == '_') {
+  for (const char c : input) {
+    if (c == '_') {
       // The field name must not contain "_"s.
       return false;
     }
-    if (input[i] >= 'A' && input[i] <= 'Z') {
+    if (c >= 'A' && c <= 'Z') {
       output->push_back('_');
-      output->push_back(input[i] + 'a' - 'A');
+      output->push_back(c + 'a' - 'A');
     } else {
-      output->push_back(input[i]);
+      output->push_back(c);
     }
   }
   return true;
@@ -125,10 +125,10 @@
 bool FieldMaskUtil::FromJsonString(StringPiece str, FieldMask* out) {
   out->Clear();
   std::vector<std::string> paths = Split(str, ",");
-  for (int i = 0; i < paths.size(); ++i) {
-    if (paths[i].empty()) continue;
+  for (const std::string& path : paths) {
+    if (path.empty()) continue;
     std::string snakecase_path;
-    if (!CamelCaseToSnakeCase(paths[i], &snakecase_path)) {
+    if (!CamelCaseToSnakeCase(path, &snakecase_path)) {
       return false;
     }
     out->add_paths(snakecase_path);
@@ -143,8 +143,7 @@
     field_descriptors->clear();
   }
   std::vector<std::string> parts = Split(path, ".");
-  for (int i = 0; i < parts.size(); ++i) {
-    const std::string& field_name = parts[i];
+  for (const std::string& field_name : parts) {
     if (descriptor == nullptr) {
       return false;
     }
@@ -332,14 +331,13 @@
   }
   bool new_branch = false;
   Node* node = &root_;
-  for (int i = 0; i < parts.size(); ++i) {
+  for (const std::string& node_name : parts) {
     if (!new_branch && node != &root_ && node->children.empty()) {
       // Path matches an existing leaf node. This means the path is already
       // covered by this tree (for example, adding "foo.bar.baz" to a tree
       // which already contains "foo.bar").
       return;
     }
-    const std::string& node_name = parts[i];
     Node*& child = node->children[node_name];
     if (child == NULL) {
       new_branch = true;
@@ -417,14 +415,13 @@
     return;
   }
   const Node* node = &root_;
-  for (int i = 0; i < parts.size(); ++i) {
+  for (const std::string& node_name : parts) {
     if (node->children.empty()) {
       if (node != &root_) {
         out->AddPath(path);
       }
       return;
     }
-    const std::string& node_name = parts[i];
     const Node* result = FindPtrOrNull(node->children, node_name);
     if (result == NULL) {
       // No intersection found.
diff --git a/src/google/protobuf/util/internal/default_value_objectwriter.cc b/src/google/protobuf/util/internal/default_value_objectwriter.cc
index d6bb788..c9c691a 100644
--- a/src/google/protobuf/util/internal/default_value_objectwriter.cc
+++ b/src/google/protobuf/util/internal/default_value_objectwriter.cc
@@ -220,8 +220,7 @@
   if (name.empty() || kind_ != OBJECT) {
     return nullptr;
   }
-  for (int i = 0; i < children_.size(); ++i) {
-    Node* child = children_[i];
+  for (Node* child : children_) {
     if (child->name() == name) {
       return child;
     }
@@ -265,8 +264,7 @@
 }
 
 void DefaultValueObjectWriter::Node::WriteChildren(ObjectWriter* ow) {
-  for (int i = 0; i < children_.size(); ++i) {
-    Node* child = children_[i];
+  for (Node* child : children_) {
     child->WriteTo(ow);
   }
 }
@@ -413,9 +411,6 @@
 DataPiece DefaultValueObjectWriter::FindEnumDefault(
     const google::protobuf::Field& field, const TypeInfo* typeinfo,
     bool use_ints_for_enums) {
-  if (!field.default_value().empty())
-    return DataPiece(field.default_value(), true);
-
   const google::protobuf::Enum* enum_type =
       typeinfo->GetEnumByTypeUrl(field.type_url());
   if (!enum_type) {
@@ -423,6 +418,26 @@
                  << "'";
     return DataPiece::NullData();
   }
+  if (!field.default_value().empty()) {
+    if (!use_ints_for_enums) {
+      return DataPiece(field.default_value(), true);
+    } else {
+      const std::string& enum_default_value_name = field.default_value();
+      for (int enum_index = 0;
+          enum_index < enum_type->enumvalue_size();
+          ++enum_index) {
+        auto& enum_value = enum_type->enumvalue(enum_index);
+        if (enum_value.name() == enum_default_value_name)
+          return DataPiece(enum_value.number());
+      }
+      GOOGLE_LOG(WARNING) << "Could not find enum value '"
+                          << enum_default_value_name
+                          << "' with type '"
+                          << field.type_url()
+                          << "'";
+      return DataPiece::NullData();
+    }
+  }
   // We treat the first value as the default if none is specified.
   return enum_type->enumvalue_size() > 0
              ? (use_ints_for_enums
diff --git a/src/google/protobuf/util/internal/expecting_objectwriter.h b/src/google/protobuf/util/internal/expecting_objectwriter.h
index 09b2e78..0f2eb1e 100644
--- a/src/google/protobuf/util/internal/expecting_objectwriter.h
+++ b/src/google/protobuf/util/internal/expecting_objectwriter.h
@@ -93,7 +93,7 @@
               (override));
   MOCK_METHOD(ObjectWriter*, RenderString,
               (StringPiece, StringPiece), (override));
-  MOCK_METHOD(ObjectWriter*, RenderBytes, (StringPiece, StringPiece));
+  MOCK_METHOD(ObjectWriter*, RenderBytes, (StringPiece, StringPiece), (override));
   MOCK_METHOD(ObjectWriter*, RenderNull, (StringPiece), (override));
 };
 
diff --git a/src/google/protobuf/util/json_format.proto b/src/google/protobuf/util/json_format.proto
index 7434fc3..7b7100d 100644
--- a/src/google/protobuf/util/json_format.proto
+++ b/src/google/protobuf/util/json_format.proto
@@ -128,3 +128,13 @@
   }
   optional string value = 1;
 }
+
+enum EnumValue {
+  PROTOCOL = 0;
+  BUFFER = 1;
+  DEFAULT = 2;
+}
+
+message TestDefaultEnumValue {
+  optional EnumValue enum_value = 1 [default = DEFAULT];
+}
diff --git a/src/google/protobuf/util/json_util_test.cc b/src/google/protobuf/util/json_util_test.cc
index c5d8315..76d3a70 100644
--- a/src/google/protobuf/util/json_util_test.cc
+++ b/src/google/protobuf/util/json_util_test.cc
@@ -241,6 +241,25 @@
   EXPECT_EQ(proto3::BAR, parsed.enum_value3());
 }
 
+TEST_F(JsonUtilTest, TestPrintProto2EnumAsIntWithDefaultValue) {
+  protobuf_unittest::TestDefaultEnumValue orig;
+
+  JsonPrintOptions print_options;
+  // use enum as int
+  print_options.always_print_enums_as_ints = true;
+  print_options.always_print_primitive_fields = true;
+
+  // result should be int rather than string
+  std::string expected_json = "{\"enumValue\":2}";
+  EXPECT_EQ(expected_json, ToJson(orig, print_options));
+
+  protobuf_unittest::TestDefaultEnumValue parsed;
+  JsonParseOptions parse_options;
+  ASSERT_TRUE(FromJson(expected_json, &parsed, parse_options));
+
+  EXPECT_EQ(protobuf_unittest::DEFAULT, parsed.enum_value());
+}
+
 TEST_F(JsonUtilTest, ParseMessage) {
   // Some random message but good enough to verify that the parsing wrapper
   // functions are working properly.
diff --git a/src/google/protobuf/wire_format_lite.h b/src/google/protobuf/wire_format_lite.h
index 18fc3ec..83668e9 100644
--- a/src/google/protobuf/wire_format_lite.h
+++ b/src/google/protobuf/wire_format_lite.h
@@ -66,13 +66,12 @@
 // #pragma pop_macro("TYPE_BOOL")
 #undef TYPE_BOOL
 
+#include <google/protobuf/port_def.inc>
 
 namespace google {
 namespace protobuf {
 namespace internal {
 
-#include <google/protobuf/port_def.inc>
-
 // This class is for internal use by the protocol buffer library and by
 // protocol-compiler-generated message classes.  It must not be called
 // directly by clients.
diff --git a/src/google/protobuf/wrappers.pb.cc b/src/google/protobuf/wrappers.pb.cc
index b581dc5..8bc8a00 100644
--- a/src/google/protobuf/wrappers.pb.cc
+++ b/src/google/protobuf/wrappers.pb.cc
@@ -270,7 +270,7 @@
   // @@protoc_insertion_point(copy_constructor:google.protobuf.DoubleValue)
 }
 
-inline void DoubleValue::SharedCtor() {
+void DoubleValue::SharedCtor() {
 value_ = 0;
 }
 
@@ -448,7 +448,7 @@
   // @@protoc_insertion_point(copy_constructor:google.protobuf.FloatValue)
 }
 
-inline void FloatValue::SharedCtor() {
+void FloatValue::SharedCtor() {
 value_ = 0;
 }
 
@@ -626,7 +626,7 @@
   // @@protoc_insertion_point(copy_constructor:google.protobuf.Int64Value)
 }
 
-inline void Int64Value::SharedCtor() {
+void Int64Value::SharedCtor() {
 value_ = int64_t{0};
 }
 
@@ -804,7 +804,7 @@
   // @@protoc_insertion_point(copy_constructor:google.protobuf.UInt64Value)
 }
 
-inline void UInt64Value::SharedCtor() {
+void UInt64Value::SharedCtor() {
 value_ = uint64_t{0u};
 }
 
@@ -982,7 +982,7 @@
   // @@protoc_insertion_point(copy_constructor:google.protobuf.Int32Value)
 }
 
-inline void Int32Value::SharedCtor() {
+void Int32Value::SharedCtor() {
 value_ = 0;
 }
 
@@ -1160,7 +1160,7 @@
   // @@protoc_insertion_point(copy_constructor:google.protobuf.UInt32Value)
 }
 
-inline void UInt32Value::SharedCtor() {
+void UInt32Value::SharedCtor() {
 value_ = 0u;
 }
 
@@ -1338,7 +1338,7 @@
   // @@protoc_insertion_point(copy_constructor:google.protobuf.BoolValue)
 }
 
-inline void BoolValue::SharedCtor() {
+void BoolValue::SharedCtor() {
 value_ = false;
 }
 
@@ -1520,7 +1520,7 @@
   // @@protoc_insertion_point(copy_constructor:google.protobuf.StringValue)
 }
 
-inline void StringValue::SharedCtor() {
+void StringValue::SharedCtor() {
 value_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
 }
 
@@ -1717,7 +1717,7 @@
   // @@protoc_insertion_point(copy_constructor:google.protobuf.BytesValue)
 }
 
-inline void BytesValue::SharedCtor() {
+void BytesValue::SharedCtor() {
 value_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
 }
 
diff --git a/src/google/protobuf/wrappers.pb.h b/src/google/protobuf/wrappers.pb.h
index 7477f5b..defdf68 100644
--- a/src/google/protobuf/wrappers.pb.h
+++ b/src/google/protobuf/wrappers.pb.h
@@ -8,12 +8,12 @@
 #include <string>
 
 #include <google/protobuf/port_def.inc>
-#if PROTOBUF_VERSION < 3015000
+#if PROTOBUF_VERSION < 3017000
 #error This file was generated by a newer version of protoc which is
 #error incompatible with your Protocol Buffer headers. Please update
 #error your headers.
 #endif
-#if 3015008 < PROTOBUF_MIN_PROTOC_VERSION
+#if 3017003 < 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.
@@ -52,7 +52,7 @@
   static const ::PROTOBUF_NAMESPACE_ID::internal::SerializationTable serialization_table[];
   static const ::PROTOBUF_NAMESPACE_ID::uint32 offsets[];
 };
-extern PROTOBUF_EXPORT const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable descriptor_table_google_2fprotobuf_2fwrappers_2eproto;
+PROTOBUF_EXPORT extern const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable descriptor_table_google_2fprotobuf_2fwrappers_2eproto;
 PROTOBUF_NAMESPACE_OPEN
 class BoolValue;
 struct BoolValueDefaultTypeInternal;