Merge pull request #9060 from protocolbuffers/toolchain

Changing toolchain names
diff --git a/CHANGES.txt b/CHANGES.txt
index fd20488..9ac2873 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -15,18 +15,44 @@
   * Generated code now uses the c++11 standard integer types int{32,64}_t and
     uint{32,64}_t
   * Reduce memory usage of the DescriptorPool type.
+  * Moved the zero-argument New() method on messages to the base class (internal
+    optimization).
+  * Unused return values marked with `PROTOBUF_MUST_USE_RESULT` are now
+    correctly attributed.
+  * Demotes PrintPath log for maps in MessageDifferencer down from WARNING to
+    INFO.
+  * Make sure FullMessageName() is always private.
+  * Fix race condition in EnumDescriptor.
+  * Remove MessageLite::GetMaybeArenaPointer.
 
   Java
   * Add @deprecated javadoc for set/get/has methods
   * correctly decode \? escape sequence in text protos
-  * Avoid depending on Objects.requireNonNull() until we can verify that no users are depending on older Android versions.
+  * Avoid depending on Objects.requireNonNull() until we can verify that no
+    users are depending on older Android versions.
   * disallow null string map values in put and putAll
+  * Add `@CheckReturnValue` to `ByteString` API.
+  * Make the `hasPresence` method public in `FieldDescriptor`.
+  * Report more detailed messages in Duration and Timestamp proto parsing
+    errors.
+  * New Timestamps.fromDate utility method that converts a java.util.Date to a
+    Timestamp proto object.
 
   Kotlin
   * Generated Kotlin code is Explicit API mode compatible
 
-Unreleased Changes (C++/Java/Python/PHP/Objective-C/C#/Ruby/JavaScript)
+2021-09-13 version 3.18.0 (C++/Java/Python/PHP/Objective-C/C#/Ruby/JavaScript)
   C++
+  * Fix warnings raised by clang 11 (#8664)
+  * Make StringPiece constructible from std::string_view (#8707)
+  * Add missing capability attributes for LLVM 12 (#8714)
+  * Stop using std::iterator (deprecated in C++17). (#8741)
+  * Move field_access_listener from libprotobuf-lite to libprotobuf (#8775)
+  * Fix #7047 Safely handle setlocale (#8735)
+  * Remove deprecated version of SetTotalBytesLimit() (#8794)
+  * Support arena allocation of google::protobuf::AnyMetadata (#8758)
+  * Fix undefined symbol error around SharedCtor() (#8827)
+  * Fix default value of enum(int) in json_util with proto2 (#8835)
   * Better Smaller ByteSizeLong
   * Introduce event filters for inject_field_listener_events
   * Reduce memory usage of DescriptorPool
@@ -50,6 +76,8 @@
   * Reduce memory usage of the DescriptorPool type.
 
   Java
+  * Fix errorprone conflict (#8723)
+  * Removing deprecated TimeUtil class. (#8749)
   * Optimized FieldDescriptor.valueOf() to avoid array copying.
   * Removing deprecated TimeUtil class.
   * Add Durations.parseUnchecked(String) and Timestamps.parseUnchecked(String)
@@ -60,6 +88,24 @@
   * Fix for optimization when reading doubles from binary wire format
   * Replace toArray implementation with toJSON.
 
+  Python
+  * Drops support for 2.7 and 3.5.
+
+  PHP
+  * Migrate PHP & Ruby to ABSL wyhash (#8854)
+  * Added support for PHP 8.1 (currently in RC1) to the C extension (#8964)
+  * Fixed PHP SEGV when constructing messages from a destructor. (#8969)
+
+  Ruby
+  * Move DSL implementation from C to pure Ruby (#8850)
+  * Fixed a memory bug with RepeatedField#+. (#8970)
+
+  Other
+  * [csharp] ByteString.CreateCodedInput should use ArraySegment offset and count (#8740)
+  * [ObjC] Add support for using the proto package to prefix symbols. (#8760)
+  * field_presence.md: fix Go example (#8788)
+
+
   Kotlin
   * Suppress NOTHING_TO_INLINE in Kotlin generated inline functions.
 
diff --git a/Makefile.am b/Makefile.am
index 7e16f69..6fb1c84 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -297,6 +297,8 @@
   java/core/src/main/java/com/google/protobuf/ByteBufferWriter.java                \
   java/core/src/main/java/com/google/protobuf/ByteOutput.java                      \
   java/core/src/main/java/com/google/protobuf/ByteString.java                      \
+  java/core/src/main/java/com/google/protobuf/CanIgnoreReturnValue.java            \
+  java/core/src/main/java/com/google/protobuf/CheckReturnValue.java                \
   java/core/src/main/java/com/google/protobuf/CodedInputStream.java                \
   java/core/src/main/java/com/google/protobuf/CodedInputStreamReader.java          \
   java/core/src/main/java/com/google/protobuf/CodedOutputStream.java               \
@@ -967,6 +969,7 @@
   php/tests/GeneratedServiceTest.php                                  \
   php/tests/MapFieldTest.php                                          \
   php/tests/memory_leak_test.php                                      \
+  php/tests/memory_leak_test.sh                                       \
   php/tests/multirequest.php                                          \
   php/tests/multirequest.sh                                           \
   php/tests/PhpImplementationTest.php                                 \
@@ -1147,19 +1150,14 @@
   ruby/lib/google/protobuf/well_known_types.rb                               \
   ruby/lib/google/protobuf.rb                                                \
   ruby/pom.xml                                                               \
-  ruby/src/main/java/com/google/protobuf/jruby/RubyBuilder.java              \
   ruby/src/main/java/com/google/protobuf/jruby/RubyDescriptor.java           \
   ruby/src/main/java/com/google/protobuf/jruby/RubyDescriptorPool.java       \
   ruby/src/main/java/com/google/protobuf/jruby/RubyEnum.java                 \
-  ruby/src/main/java/com/google/protobuf/jruby/RubyEnumBuilderContext.java   \
   ruby/src/main/java/com/google/protobuf/jruby/RubyEnumDescriptor.java       \
   ruby/src/main/java/com/google/protobuf/jruby/RubyFieldDescriptor.java      \
-  ruby/src/main/java/com/google/protobuf/jruby/RubyFileBuilderContext.java   \
   ruby/src/main/java/com/google/protobuf/jruby/RubyFileDescriptor.java       \
   ruby/src/main/java/com/google/protobuf/jruby/RubyMap.java                  \
   ruby/src/main/java/com/google/protobuf/jruby/RubyMessage.java              \
-  ruby/src/main/java/com/google/protobuf/jruby/RubyMessageBuilderContext.java \
-  ruby/src/main/java/com/google/protobuf/jruby/RubyOneofBuilderContext.java  \
   ruby/src/main/java/com/google/protobuf/jruby/RubyOneofDescriptor.java      \
   ruby/src/main/java/com/google/protobuf/jruby/RubyProtobuf.java             \
   ruby/src/main/java/com/google/protobuf/jruby/RubyRepeatedField.java        \
diff --git a/Protobuf-C++.podspec b/Protobuf-C++.podspec
index 2e81a7c..4a524e6 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.17.3'
+  s.version  = '3.18.0'
   s.summary  = 'Protocol Buffers v3 runtime library for C++.'
   s.homepage = 'https://github.com/google/protobuf'
   s.license  = '3-Clause BSD License'
@@ -21,7 +21,8 @@
                     'src/google/**/*_unittest.{h,cc}',
                     'src/google/protobuf/test_util*.{h,cc}',
                     'src/google/protobuf/map_lite_test_util.{h,cc}',
-                    'src/google/protobuf/map_test_util*.{h,cc,inc}'
+                    'src/google/protobuf/map_test_util*.{h,cc,inc}',
+                    'src/google/protobuf/reflection_tester.{h,cc}'
 
   s.header_mappings_dir = 'src'
 
diff --git a/Protobuf.podspec b/Protobuf.podspec
index c1b4795..a3c4380 100644
--- a/Protobuf.podspec
+++ b/Protobuf.podspec
@@ -5,7 +5,7 @@
 # dependent projects use the :git notation to refer to the library.
 Pod::Spec.new do |s|
   s.name     = 'Protobuf'
-  s.version  = '3.17.3'
+  s.version  = '3.18.0'
   s.summary  = 'Protocol Buffers v.3 runtime library for Objective-C.'
   s.homepage = 'https://github.com/protocolbuffers/protobuf'
   s.license  = '3-Clause BSD License'
diff --git a/cmake/install.cmake b/cmake/install.cmake
index ef5bb13..4e1c5de 100644
--- a/cmake/install.cmake
+++ b/cmake/install.cmake
@@ -30,9 +30,8 @@
 
 if (protobuf_BUILD_PROTOC_BINARIES)
   install(TARGETS protoc EXPORT protobuf-targets
-    RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
-    BUNDLE DESTINATION ${CMAKE_INSTALL_BINDIR}
-    COMPONENT protoc)
+    RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT protoc
+    BUNDLE DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT protoc)
   if (UNIX AND NOT APPLE)
     set_property(TARGET protoc
       PROPERTY INSTALL_RPATH "$ORIGIN/../${CMAKE_INSTALL_LIBDIR}")
diff --git a/cmake/libprotobuf-lite.cmake b/cmake/libprotobuf-lite.cmake
index 95b7f1f..024a4ee 100644
--- a/cmake/libprotobuf-lite.cmake
+++ b/cmake/libprotobuf-lite.cmake
@@ -37,6 +37,7 @@
   ${protobuf_source_dir}/src/google/protobuf/arena.h
   ${protobuf_source_dir}/src/google/protobuf/arena_impl.h
   ${protobuf_source_dir}/src/google/protobuf/arenastring.h
+  ${protobuf_source_dir}/src/google/protobuf/explicitly_constructed.h
   ${protobuf_source_dir}/src/google/protobuf/extension_set.h
   ${protobuf_source_dir}/src/google/protobuf/extension_set_inl.h
   ${protobuf_source_dir}/src/google/protobuf/generated_enum_util.h
diff --git a/cmake/libprotobuf.cmake b/cmake/libprotobuf.cmake
index 668b8c2..e4b810c 100644
--- a/cmake/libprotobuf.cmake
+++ b/cmake/libprotobuf.cmake
@@ -21,6 +21,7 @@
   ${protobuf_source_dir}/src/google/protobuf/io/tokenizer.cc
   ${protobuf_source_dir}/src/google/protobuf/map_field.cc
   ${protobuf_source_dir}/src/google/protobuf/message.cc
+  ${protobuf_source_dir}/src/google/protobuf/reflection_internal.h
   ${protobuf_source_dir}/src/google/protobuf/reflection_ops.cc
   ${protobuf_source_dir}/src/google/protobuf/service.cc
   ${protobuf_source_dir}/src/google/protobuf/source_context.pb.cc
diff --git a/cmake/libprotoc.cmake b/cmake/libprotoc.cmake
index 6f04331..505e469 100644
--- a/cmake/libprotoc.cmake
+++ b/cmake/libprotoc.cmake
@@ -36,6 +36,7 @@
   ${protobuf_source_dir}/src/google/protobuf/compiler/java/java_doc_comment.cc
   ${protobuf_source_dir}/src/google/protobuf/compiler/java/java_enum.cc
   ${protobuf_source_dir}/src/google/protobuf/compiler/java/java_enum_field.cc
+  ${protobuf_source_dir}/src/google/protobuf/compiler/java/java_enum_field.h
   ${protobuf_source_dir}/src/google/protobuf/compiler/java/java_enum_field_lite.cc
   ${protobuf_source_dir}/src/google/protobuf/compiler/java/java_enum_lite.cc
   ${protobuf_source_dir}/src/google/protobuf/compiler/java/java_extension.cc
@@ -64,17 +65,28 @@
   ${protobuf_source_dir}/src/google/protobuf/compiler/js/js_generator.cc
   ${protobuf_source_dir}/src/google/protobuf/compiler/js/well_known_types_embed.cc
   ${protobuf_source_dir}/src/google/protobuf/compiler/objectivec/objectivec_enum.cc
+  ${protobuf_source_dir}/src/google/protobuf/compiler/objectivec/objectivec_enum.h
   ${protobuf_source_dir}/src/google/protobuf/compiler/objectivec/objectivec_enum_field.cc
+  ${protobuf_source_dir}/src/google/protobuf/compiler/objectivec/objectivec_enum_field.h
   ${protobuf_source_dir}/src/google/protobuf/compiler/objectivec/objectivec_extension.cc
+  ${protobuf_source_dir}/src/google/protobuf/compiler/objectivec/objectivec_extension.h
   ${protobuf_source_dir}/src/google/protobuf/compiler/objectivec/objectivec_field.cc
+  ${protobuf_source_dir}/src/google/protobuf/compiler/objectivec/objectivec_field.h
   ${protobuf_source_dir}/src/google/protobuf/compiler/objectivec/objectivec_file.cc
+  ${protobuf_source_dir}/src/google/protobuf/compiler/objectivec/objectivec_file.h
   ${protobuf_source_dir}/src/google/protobuf/compiler/objectivec/objectivec_generator.cc
   ${protobuf_source_dir}/src/google/protobuf/compiler/objectivec/objectivec_helpers.cc
   ${protobuf_source_dir}/src/google/protobuf/compiler/objectivec/objectivec_map_field.cc
+  ${protobuf_source_dir}/src/google/protobuf/compiler/objectivec/objectivec_map_field.h
   ${protobuf_source_dir}/src/google/protobuf/compiler/objectivec/objectivec_message.cc
+  ${protobuf_source_dir}/src/google/protobuf/compiler/objectivec/objectivec_message.h
   ${protobuf_source_dir}/src/google/protobuf/compiler/objectivec/objectivec_message_field.cc
+  ${protobuf_source_dir}/src/google/protobuf/compiler/objectivec/objectivec_message_field.h
+  ${protobuf_source_dir}/src/google/protobuf/compiler/objectivec/objectivec_nsobject_methods.h
   ${protobuf_source_dir}/src/google/protobuf/compiler/objectivec/objectivec_oneof.cc
+  ${protobuf_source_dir}/src/google/protobuf/compiler/objectivec/objectivec_oneof.h
   ${protobuf_source_dir}/src/google/protobuf/compiler/objectivec/objectivec_primitive_field.cc
+  ${protobuf_source_dir}/src/google/protobuf/compiler/objectivec/objectivec_primitive_field.h
   ${protobuf_source_dir}/src/google/protobuf/compiler/php/php_generator.cc
   ${protobuf_source_dir}/src/google/protobuf/compiler/plugin.cc
   ${protobuf_source_dir}/src/google/protobuf/compiler/plugin.pb.cc
@@ -82,6 +94,7 @@
   ${protobuf_source_dir}/src/google/protobuf/compiler/ruby/ruby_generator.cc
   ${protobuf_source_dir}/src/google/protobuf/compiler/subprocess.cc
   ${protobuf_source_dir}/src/google/protobuf/compiler/zip_writer.cc
+  ${protobuf_source_dir}/src/google/protobuf/compiler/zip_writer.h
 )
 
 set(libprotoc_headers
@@ -95,17 +108,14 @@
   ${protobuf_source_dir}/src/google/protobuf/compiler/csharp/csharp_generator.h
   ${protobuf_source_dir}/src/google/protobuf/compiler/csharp/csharp_names.h
   ${protobuf_source_dir}/src/google/protobuf/compiler/csharp/csharp_options.h
-  ${protobuf_source_dir}/src/google/protobuf/compiler/importer.h
   ${protobuf_source_dir}/src/google/protobuf/compiler/java/java_generator.h
   ${protobuf_source_dir}/src/google/protobuf/compiler/java/java_kotlin_generator.h
   ${protobuf_source_dir}/src/google/protobuf/compiler/java/java_names.h
   ${protobuf_source_dir}/src/google/protobuf/compiler/js/js_generator.h
   ${protobuf_source_dir}/src/google/protobuf/compiler/objectivec/objectivec_generator.h
   ${protobuf_source_dir}/src/google/protobuf/compiler/objectivec/objectivec_helpers.h
-  ${protobuf_source_dir}/src/google/protobuf/compiler/parser.h
   ${protobuf_source_dir}/src/google/protobuf/compiler/php/php_generator.h
   ${protobuf_source_dir}/src/google/protobuf/compiler/plugin.h
-  ${protobuf_source_dir}/src/google/protobuf/compiler/plugin.pb.h
   ${protobuf_source_dir}/src/google/protobuf/compiler/python/python_generator.h
   ${protobuf_source_dir}/src/google/protobuf/compiler/ruby/ruby_generator.h
 )
diff --git a/cmake/tests.cmake b/cmake/tests.cmake
index 5296858..9ede4f3 100644
--- a/cmake/tests.cmake
+++ b/cmake/tests.cmake
@@ -119,10 +119,10 @@
 
 set(common_test_files
   ${common_lite_test_files}
+  ${protobuf_source_dir}/src/google/protobuf/compiler/mock_code_generator.cc
   ${protobuf_source_dir}/src/google/protobuf/map_test_util.inc
   ${protobuf_source_dir}/src/google/protobuf/reflection_tester.cc
   ${protobuf_source_dir}/src/google/protobuf/test_util.cc
-  ${protobuf_source_dir}/src/google/protobuf/test_util.inc
   ${protobuf_source_dir}/src/google/protobuf/testing/file.cc
   ${protobuf_source_dir}/src/google/protobuf/testing/googletest.cc
 )
@@ -132,6 +132,7 @@
   ${protobuf_source_dir}/src/google/protobuf/arena_unittest.cc
   ${protobuf_source_dir}/src/google/protobuf/arenastring_unittest.cc
   ${protobuf_source_dir}/src/google/protobuf/compiler/annotation_test_util.cc
+  ${protobuf_source_dir}/src/google/protobuf/compiler/annotation_test_util.h
   ${protobuf_source_dir}/src/google/protobuf/compiler/command_line_interface_unittest.cc
   ${protobuf_source_dir}/src/google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc
   ${protobuf_source_dir}/src/google/protobuf/compiler/cpp/cpp_move_unittest.cc
@@ -144,7 +145,6 @@
   ${protobuf_source_dir}/src/google/protobuf/compiler/importer_unittest.cc
   ${protobuf_source_dir}/src/google/protobuf/compiler/java/java_doc_comment_unittest.cc
   ${protobuf_source_dir}/src/google/protobuf/compiler/java/java_plugin_unittest.cc
-  ${protobuf_source_dir}/src/google/protobuf/compiler/mock_code_generator.cc
   ${protobuf_source_dir}/src/google/protobuf/compiler/objectivec/objectivec_helpers_unittest.cc
   ${protobuf_source_dir}/src/google/protobuf/compiler/parser_unittest.cc
   ${protobuf_source_dir}/src/google/protobuf/compiler/python/python_plugin_unittest.cc
diff --git a/configure.ac b/configure.ac
index a3309b7..829568f 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.17.3],[[email protected]],[protobuf])
+AC_INIT([Protocol Buffers],[3.18.0],[[email protected]],[protobuf])
 
 AM_MAINTAINER_MODE([enable])
 
diff --git a/conformance/failure_list_jruby.txt b/conformance/failure_list_jruby.txt
index ceaaf92..516192e 100644
--- a/conformance/failure_list_jruby.txt
+++ b/conformance/failure_list_jruby.txt
@@ -2,6 +2,34 @@
 Recommended.FieldMaskPathsDontRoundTrip.JsonOutput
 Recommended.FieldMaskTooManyUnderscore.JsonOutput
 Recommended.Proto2.JsonInput.FieldNameExtension.Validator
+Recommended.Proto2.ProtobufInput.ValidDataRepeated.BOOL.PackedInput.PackedOutput.ProtobufOutput
+Recommended.Proto2.ProtobufInput.ValidDataRepeated.BOOL.UnpackedInput.PackedOutput.ProtobufOutput
+Recommended.Proto2.ProtobufInput.ValidDataRepeated.DOUBLE.PackedInput.PackedOutput.ProtobufOutput
+Recommended.Proto2.ProtobufInput.ValidDataRepeated.DOUBLE.UnpackedInput.PackedOutput.ProtobufOutput
+Recommended.Proto2.ProtobufInput.ValidDataRepeated.ENUM.PackedInput.PackedOutput.ProtobufOutput
+Recommended.Proto2.ProtobufInput.ValidDataRepeated.ENUM.UnpackedInput.PackedOutput.ProtobufOutput
+Recommended.Proto2.ProtobufInput.ValidDataRepeated.FIXED32.PackedInput.PackedOutput.ProtobufOutput
+Recommended.Proto2.ProtobufInput.ValidDataRepeated.FIXED32.UnpackedInput.PackedOutput.ProtobufOutput
+Recommended.Proto2.ProtobufInput.ValidDataRepeated.FIXED64.PackedInput.PackedOutput.ProtobufOutput
+Recommended.Proto2.ProtobufInput.ValidDataRepeated.FIXED64.UnpackedInput.PackedOutput.ProtobufOutput
+Recommended.Proto2.ProtobufInput.ValidDataRepeated.FLOAT.PackedInput.PackedOutput.ProtobufOutput
+Recommended.Proto2.ProtobufInput.ValidDataRepeated.FLOAT.UnpackedInput.PackedOutput.ProtobufOutput
+Recommended.Proto2.ProtobufInput.ValidDataRepeated.INT32.PackedInput.PackedOutput.ProtobufOutput
+Recommended.Proto2.ProtobufInput.ValidDataRepeated.INT32.UnpackedInput.PackedOutput.ProtobufOutput
+Recommended.Proto2.ProtobufInput.ValidDataRepeated.INT64.PackedInput.PackedOutput.ProtobufOutput
+Recommended.Proto2.ProtobufInput.ValidDataRepeated.INT64.UnpackedInput.PackedOutput.ProtobufOutput
+Recommended.Proto2.ProtobufInput.ValidDataRepeated.SFIXED32.PackedInput.PackedOutput.ProtobufOutput
+Recommended.Proto2.ProtobufInput.ValidDataRepeated.SFIXED32.UnpackedInput.PackedOutput.ProtobufOutput
+Recommended.Proto2.ProtobufInput.ValidDataRepeated.SFIXED64.PackedInput.PackedOutput.ProtobufOutput
+Recommended.Proto2.ProtobufInput.ValidDataRepeated.SFIXED64.UnpackedInput.PackedOutput.ProtobufOutput
+Recommended.Proto2.ProtobufInput.ValidDataRepeated.SINT32.PackedInput.PackedOutput.ProtobufOutput
+Recommended.Proto2.ProtobufInput.ValidDataRepeated.SINT32.UnpackedInput.PackedOutput.ProtobufOutput
+Recommended.Proto2.ProtobufInput.ValidDataRepeated.SINT64.PackedInput.PackedOutput.ProtobufOutput
+Recommended.Proto2.ProtobufInput.ValidDataRepeated.SINT64.UnpackedInput.PackedOutput.ProtobufOutput
+Recommended.Proto2.ProtobufInput.ValidDataRepeated.UINT32.PackedInput.PackedOutput.ProtobufOutput
+Recommended.Proto2.ProtobufInput.ValidDataRepeated.UINT32.UnpackedInput.PackedOutput.ProtobufOutput
+Recommended.Proto2.ProtobufInput.ValidDataRepeated.UINT64.PackedInput.PackedOutput.ProtobufOutput
+Recommended.Proto2.ProtobufInput.ValidDataRepeated.UINT64.UnpackedInput.PackedOutput.ProtobufOutput
 Recommended.Proto3.JsonInput.BoolFieldAllCapitalFalse
 Recommended.Proto3.JsonInput.BoolFieldAllCapitalTrue
 Recommended.Proto3.JsonInput.BoolFieldCamelCaseFalse
@@ -29,782 +57,39 @@
 Recommended.Proto3.JsonInput.StringFieldUnpairedLowSurrogate
 Recommended.Proto3.JsonInput.Uint32MapFieldKeyNotQuoted
 Recommended.Proto3.JsonInput.Uint64MapFieldKeyNotQuoted
-Recommended.Proto3.ProtobufInput.OneofZeroBool.JsonOutput
-Recommended.Proto3.ProtobufInput.OneofZeroBool.ProtobufOutput
-Recommended.Proto3.ProtobufInput.OneofZeroBytes.JsonOutput
-Recommended.Proto3.ProtobufInput.OneofZeroBytes.ProtobufOutput
-Recommended.Proto3.ProtobufInput.OneofZeroDouble.JsonOutput
-Recommended.Proto3.ProtobufInput.OneofZeroDouble.ProtobufOutput
-Recommended.Proto3.ProtobufInput.OneofZeroEnum.JsonOutput
-Recommended.Proto3.ProtobufInput.OneofZeroEnum.ProtobufOutput
-Recommended.Proto3.ProtobufInput.OneofZeroFloat.JsonOutput
-Recommended.Proto3.ProtobufInput.OneofZeroFloat.ProtobufOutput
-Recommended.Proto3.ProtobufInput.OneofZeroMessage.JsonOutput
-Recommended.Proto3.ProtobufInput.OneofZeroMessage.ProtobufOutput
-Recommended.Proto3.ProtobufInput.OneofZeroMessageSetTwice.JsonOutput
-Recommended.Proto3.ProtobufInput.OneofZeroMessageSetTwice.ProtobufOutput
-Recommended.Proto3.ProtobufInput.OneofZeroString.JsonOutput
-Recommended.Proto3.ProtobufInput.OneofZeroString.ProtobufOutput
-Recommended.Proto3.ProtobufInput.OneofZeroUint32.JsonOutput
-Recommended.Proto3.ProtobufInput.OneofZeroUint32.ProtobufOutput
-Recommended.Proto3.ProtobufInput.OneofZeroUint64.JsonOutput
-Recommended.Proto3.ProtobufInput.OneofZeroUint64.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataOneofBinary.BOOL.DefaultValue.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataOneofBinary.BOOL.MultipleValuesForDifferentField.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataOneofBinary.BOOL.MultipleValuesForSameField.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataOneofBinary.BOOL.NonDefaultValue.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataOneofBinary.BYTES.DefaultValue.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataOneofBinary.BYTES.MultipleValuesForDifferentField.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataOneofBinary.BYTES.MultipleValuesForSameField.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataOneofBinary.BYTES.NonDefaultValue.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataOneofBinary.DOUBLE.DefaultValue.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataOneofBinary.DOUBLE.MultipleValuesForDifferentField.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataOneofBinary.DOUBLE.MultipleValuesForSameField.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataOneofBinary.DOUBLE.NonDefaultValue.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataOneofBinary.ENUM.DefaultValue.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataOneofBinary.ENUM.MultipleValuesForDifferentField.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataOneofBinary.ENUM.MultipleValuesForSameField.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataOneofBinary.ENUM.NonDefaultValue.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataOneofBinary.FLOAT.DefaultValue.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataOneofBinary.FLOAT.MultipleValuesForDifferentField.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataOneofBinary.FLOAT.MultipleValuesForSameField.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataOneofBinary.FLOAT.NonDefaultValue.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataOneofBinary.MESSAGE.DefaultValue.ProtobufOutput
 Recommended.Proto3.ProtobufInput.ValidDataOneofBinary.MESSAGE.Merge.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataOneofBinary.MESSAGE.MultipleValuesForDifferentField.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataOneofBinary.MESSAGE.MultipleValuesForSameField.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataOneofBinary.MESSAGE.NonDefaultValue.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataOneofBinary.STRING.DefaultValue.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataOneofBinary.STRING.MultipleValuesForDifferentField.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataOneofBinary.STRING.MultipleValuesForSameField.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataOneofBinary.STRING.NonDefaultValue.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataOneofBinary.UINT32.DefaultValue.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataOneofBinary.UINT32.MultipleValuesForDifferentField.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataOneofBinary.UINT32.MultipleValuesForSameField.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataOneofBinary.UINT32.NonDefaultValue.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataOneofBinary.UINT64.DefaultValue.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataOneofBinary.UINT64.MultipleValuesForDifferentField.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataOneofBinary.UINT64.MultipleValuesForSameField.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataOneofBinary.UINT64.NonDefaultValue.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.BOOL.PackedInput.DefaultOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.BOOL.PackedInput.PackedOutput.ProtobufOutput
 Recommended.Proto3.ProtobufInput.ValidDataRepeated.BOOL.PackedInput.UnpackedOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.BOOL.UnpackedInput.DefaultOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.BOOL.UnpackedInput.PackedOutput.ProtobufOutput
 Recommended.Proto3.ProtobufInput.ValidDataRepeated.BOOL.UnpackedInput.UnpackedOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.DOUBLE.PackedInput.DefaultOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.DOUBLE.PackedInput.PackedOutput.ProtobufOutput
 Recommended.Proto3.ProtobufInput.ValidDataRepeated.DOUBLE.PackedInput.UnpackedOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.DOUBLE.UnpackedInput.DefaultOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.DOUBLE.UnpackedInput.PackedOutput.ProtobufOutput
 Recommended.Proto3.ProtobufInput.ValidDataRepeated.DOUBLE.UnpackedInput.UnpackedOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.ENUM.PackedInput.DefaultOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.ENUM.PackedInput.PackedOutput.ProtobufOutput
 Recommended.Proto3.ProtobufInput.ValidDataRepeated.ENUM.PackedInput.UnpackedOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.ENUM.UnpackedInput.DefaultOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.ENUM.UnpackedInput.PackedOutput.ProtobufOutput
 Recommended.Proto3.ProtobufInput.ValidDataRepeated.ENUM.UnpackedInput.UnpackedOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.FIXED32.PackedInput.DefaultOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.FIXED32.PackedInput.PackedOutput.ProtobufOutput
 Recommended.Proto3.ProtobufInput.ValidDataRepeated.FIXED32.PackedInput.UnpackedOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.FIXED32.UnpackedInput.DefaultOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.FIXED32.UnpackedInput.PackedOutput.ProtobufOutput
 Recommended.Proto3.ProtobufInput.ValidDataRepeated.FIXED32.UnpackedInput.UnpackedOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.FIXED64.PackedInput.DefaultOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.FIXED64.PackedInput.PackedOutput.ProtobufOutput
 Recommended.Proto3.ProtobufInput.ValidDataRepeated.FIXED64.PackedInput.UnpackedOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.FIXED64.UnpackedInput.DefaultOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.FIXED64.UnpackedInput.PackedOutput.ProtobufOutput
 Recommended.Proto3.ProtobufInput.ValidDataRepeated.FIXED64.UnpackedInput.UnpackedOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.FLOAT.PackedInput.DefaultOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.FLOAT.PackedInput.PackedOutput.ProtobufOutput
 Recommended.Proto3.ProtobufInput.ValidDataRepeated.FLOAT.PackedInput.UnpackedOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.FLOAT.UnpackedInput.DefaultOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.FLOAT.UnpackedInput.PackedOutput.ProtobufOutput
 Recommended.Proto3.ProtobufInput.ValidDataRepeated.FLOAT.UnpackedInput.UnpackedOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT32.PackedInput.DefaultOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT32.PackedInput.PackedOutput.ProtobufOutput
 Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT32.PackedInput.UnpackedOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT32.UnpackedInput.DefaultOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT32.UnpackedInput.PackedOutput.ProtobufOutput
 Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT32.UnpackedInput.UnpackedOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT64.PackedInput.DefaultOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT64.PackedInput.PackedOutput.ProtobufOutput
 Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT64.PackedInput.UnpackedOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT64.UnpackedInput.DefaultOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT64.UnpackedInput.PackedOutput.ProtobufOutput
 Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT64.UnpackedInput.UnpackedOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.SFIXED32.PackedInput.DefaultOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.SFIXED32.PackedInput.PackedOutput.ProtobufOutput
 Recommended.Proto3.ProtobufInput.ValidDataRepeated.SFIXED32.PackedInput.UnpackedOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.SFIXED32.UnpackedInput.DefaultOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.SFIXED32.UnpackedInput.PackedOutput.ProtobufOutput
 Recommended.Proto3.ProtobufInput.ValidDataRepeated.SFIXED32.UnpackedInput.UnpackedOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.SFIXED64.PackedInput.DefaultOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.SFIXED64.PackedInput.PackedOutput.ProtobufOutput
 Recommended.Proto3.ProtobufInput.ValidDataRepeated.SFIXED64.PackedInput.UnpackedOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.SFIXED64.UnpackedInput.DefaultOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.SFIXED64.UnpackedInput.PackedOutput.ProtobufOutput
 Recommended.Proto3.ProtobufInput.ValidDataRepeated.SFIXED64.UnpackedInput.UnpackedOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.SINT32.PackedInput.DefaultOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.SINT32.PackedInput.PackedOutput.ProtobufOutput
 Recommended.Proto3.ProtobufInput.ValidDataRepeated.SINT32.PackedInput.UnpackedOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.SINT32.UnpackedInput.DefaultOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.SINT32.UnpackedInput.PackedOutput.ProtobufOutput
 Recommended.Proto3.ProtobufInput.ValidDataRepeated.SINT32.UnpackedInput.UnpackedOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.SINT64.PackedInput.DefaultOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.SINT64.PackedInput.PackedOutput.ProtobufOutput
 Recommended.Proto3.ProtobufInput.ValidDataRepeated.SINT64.PackedInput.UnpackedOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.SINT64.UnpackedInput.DefaultOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.SINT64.UnpackedInput.PackedOutput.ProtobufOutput
 Recommended.Proto3.ProtobufInput.ValidDataRepeated.SINT64.UnpackedInput.UnpackedOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT32.PackedInput.DefaultOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT32.PackedInput.PackedOutput.ProtobufOutput
 Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT32.PackedInput.UnpackedOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT32.UnpackedInput.DefaultOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT32.UnpackedInput.PackedOutput.ProtobufOutput
 Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT32.UnpackedInput.UnpackedOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT64.PackedInput.DefaultOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT64.PackedInput.PackedOutput.ProtobufOutput
 Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT64.PackedInput.UnpackedOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT64.UnpackedInput.DefaultOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT64.UnpackedInput.PackedOutput.ProtobufOutput
 Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT64.UnpackedInput.UnpackedOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.BOOL[2].ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.BOOL[3].ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.BOOL[4].ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.BOOL[5].ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.BOOL[6].ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.BYTES[3].ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.DOUBLE[1].ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.DOUBLE[2].ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.ENUM[0].ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.ENUM[1].ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.ENUM[2].ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.ENUM[3].ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.ENUM[4].ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.ENUM[5].ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.FIXED32[2].ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.FIXED64[2].ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.FLOAT[1].ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.FLOAT[2].ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.FLOAT[3].ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.FLOAT[4].ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.INT32[1].ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.INT32[2].ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.INT32[3].ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.INT32[4].ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.INT32[5].ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.INT32[6].ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.INT32[7].ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.INT32[8].ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.INT32[9].ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.INT64[1].ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.INT64[2].ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.INT64[3].ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.MESSAGE[0].ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.MESSAGE[1].ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.SFIXED32[2].ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.SFIXED32[3].ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.SFIXED64[2].ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.SFIXED64[3].ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.SINT32[1].ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.SINT32[2].ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.SINT32[3].ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.SINT32[4].ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.SINT64[1].ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.SINT64[2].ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.SINT64[3].ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.STRING[3].ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.STRING[4].ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.STRING[5].ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.STRING[6].ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.UINT32[1].ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.UINT32[2].ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.UINT32[3].ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.UINT32[4].ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.UINT32[5].ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.UINT32[6].ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.UINT32[7].ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.UINT32[8].ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.UINT32[9].ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.UINT64[1].ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.UINT64[2].ProtobufOutput
-Required.DurationProtoInputTooLarge.JsonOutput
-Required.DurationProtoInputTooSmall.JsonOutput
-Required.Proto2.JsonInput.StoresDefaultPrimitive.Validator
-Required.Proto3.JsonInput.Any.JsonOutput
-Required.Proto3.JsonInput.Any.ProtobufOutput
-Required.Proto3.JsonInput.AnyNested.JsonOutput
-Required.Proto3.JsonInput.AnyNested.ProtobufOutput
-Required.Proto3.JsonInput.AnyUnorderedTypeTag.JsonOutput
-Required.Proto3.JsonInput.AnyUnorderedTypeTag.ProtobufOutput
-Required.Proto3.JsonInput.AnyWithDuration.JsonOutput
-Required.Proto3.JsonInput.AnyWithDuration.ProtobufOutput
-Required.Proto3.JsonInput.AnyWithFieldMask.JsonOutput
-Required.Proto3.JsonInput.AnyWithFieldMask.ProtobufOutput
-Required.Proto3.JsonInput.AnyWithInt32ValueWrapper.JsonOutput
-Required.Proto3.JsonInput.AnyWithInt32ValueWrapper.ProtobufOutput
-Required.Proto3.JsonInput.AnyWithStruct.JsonOutput
-Required.Proto3.JsonInput.AnyWithStruct.ProtobufOutput
-Required.Proto3.JsonInput.AnyWithTimestamp.JsonOutput
-Required.Proto3.JsonInput.AnyWithTimestamp.ProtobufOutput
-Required.Proto3.JsonInput.AnyWithValueForInteger.JsonOutput
-Required.Proto3.JsonInput.AnyWithValueForInteger.ProtobufOutput
-Required.Proto3.JsonInput.AnyWithValueForJsonObject.JsonOutput
-Required.Proto3.JsonInput.AnyWithValueForJsonObject.ProtobufOutput
 Required.Proto3.JsonInput.EnumFieldNotQuoted
-Required.Proto3.JsonInput.IgnoreUnknownJsonFalse.ProtobufOutput
-Required.Proto3.JsonInput.IgnoreUnknownJsonNull.ProtobufOutput
-Required.Proto3.JsonInput.IgnoreUnknownJsonNumber.ProtobufOutput
-Required.Proto3.JsonInput.IgnoreUnknownJsonObject.ProtobufOutput
-Required.Proto3.JsonInput.IgnoreUnknownJsonString.ProtobufOutput
-Required.Proto3.JsonInput.IgnoreUnknownJsonTrue.ProtobufOutput
 Required.Proto3.JsonInput.Int32FieldLeadingZero
 Required.Proto3.JsonInput.Int32FieldNegativeWithLeadingZero
 Required.Proto3.JsonInput.Int32FieldPlusSign
 Required.Proto3.JsonInput.RepeatedFieldWrongElementTypeExpectingStringsGotBool
 Required.Proto3.JsonInput.RepeatedFieldWrongElementTypeExpectingStringsGotInt
 Required.Proto3.JsonInput.StringFieldNotAString
-Required.Proto3.ProtobufInput.DoubleFieldNormalizeQuietNan.JsonOutput
-Required.Proto3.ProtobufInput.DoubleFieldNormalizeSignalingNan.JsonOutput
-Required.Proto3.ProtobufInput.FloatFieldNormalizeQuietNan.JsonOutput
-Required.Proto3.ProtobufInput.FloatFieldNormalizeSignalingNan.JsonOutput
-Required.Proto3.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.BOOL
-Required.Proto3.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.INT32
-Required.Proto3.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.INT64
-Required.Proto3.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.SINT32
-Required.Proto3.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.SINT64
-Required.Proto3.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.UINT32
-Required.Proto3.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.UINT64
-Required.Proto3.ProtobufInput.RepeatedScalarMessageMerge.JsonOutput
-Required.Proto3.ProtobufInput.RepeatedScalarMessageMerge.ProtobufOutput
-Required.Proto3.ProtobufInput.RepeatedScalarSelectsLast.BOOL.JsonOutput
-Required.Proto3.ProtobufInput.RepeatedScalarSelectsLast.BOOL.ProtobufOutput
-Required.Proto3.ProtobufInput.RepeatedScalarSelectsLast.BYTES.JsonOutput
-Required.Proto3.ProtobufInput.RepeatedScalarSelectsLast.BYTES.ProtobufOutput
-Required.Proto3.ProtobufInput.RepeatedScalarSelectsLast.ENUM.JsonOutput
-Required.Proto3.ProtobufInput.RepeatedScalarSelectsLast.ENUM.ProtobufOutput
-Required.Proto3.ProtobufInput.RepeatedScalarSelectsLast.FIXED32.JsonOutput
-Required.Proto3.ProtobufInput.RepeatedScalarSelectsLast.FIXED32.ProtobufOutput
-Required.Proto3.ProtobufInput.RepeatedScalarSelectsLast.FIXED64.JsonOutput
-Required.Proto3.ProtobufInput.RepeatedScalarSelectsLast.FIXED64.ProtobufOutput
-Required.Proto3.ProtobufInput.RepeatedScalarSelectsLast.FLOAT.JsonOutput
-Required.Proto3.ProtobufInput.RepeatedScalarSelectsLast.FLOAT.ProtobufOutput
-Required.Proto3.ProtobufInput.RepeatedScalarSelectsLast.INT32.JsonOutput
-Required.Proto3.ProtobufInput.RepeatedScalarSelectsLast.INT32.ProtobufOutput
-Required.Proto3.ProtobufInput.RepeatedScalarSelectsLast.INT64.JsonOutput
-Required.Proto3.ProtobufInput.RepeatedScalarSelectsLast.INT64.ProtobufOutput
-Required.Proto3.ProtobufInput.RepeatedScalarSelectsLast.SFIXED32.JsonOutput
-Required.Proto3.ProtobufInput.RepeatedScalarSelectsLast.SFIXED32.ProtobufOutput
-Required.Proto3.ProtobufInput.RepeatedScalarSelectsLast.SFIXED64.JsonOutput
-Required.Proto3.ProtobufInput.RepeatedScalarSelectsLast.SFIXED64.ProtobufOutput
-Required.Proto3.ProtobufInput.RepeatedScalarSelectsLast.SINT32.JsonOutput
-Required.Proto3.ProtobufInput.RepeatedScalarSelectsLast.SINT32.ProtobufOutput
-Required.Proto3.ProtobufInput.RepeatedScalarSelectsLast.SINT64.JsonOutput
-Required.Proto3.ProtobufInput.RepeatedScalarSelectsLast.SINT64.ProtobufOutput
-Required.Proto3.ProtobufInput.RepeatedScalarSelectsLast.STRING.JsonOutput
-Required.Proto3.ProtobufInput.RepeatedScalarSelectsLast.STRING.ProtobufOutput
-Required.Proto3.ProtobufInput.RepeatedScalarSelectsLast.UINT32.JsonOutput
-Required.Proto3.ProtobufInput.RepeatedScalarSelectsLast.UINT32.ProtobufOutput
-Required.Proto3.ProtobufInput.RepeatedScalarSelectsLast.UINT64.JsonOutput
-Required.Proto3.ProtobufInput.RepeatedScalarSelectsLast.UINT64.ProtobufOutput
-Required.Proto3.ProtobufInput.UnknownVarint.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataMap.BOOL.BOOL.Default.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataMap.BOOL.BOOL.Default.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataMap.BOOL.BOOL.DuplicateKey.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataMap.BOOL.BOOL.DuplicateKey.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataMap.BOOL.BOOL.DuplicateKeyInMapEntry.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataMap.BOOL.BOOL.DuplicateKeyInMapEntry.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataMap.BOOL.BOOL.DuplicateValueInMapEntry.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataMap.BOOL.BOOL.DuplicateValueInMapEntry.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataMap.BOOL.BOOL.MissingDefault.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataMap.BOOL.BOOL.MissingDefault.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataMap.BOOL.BOOL.NonDefault.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataMap.BOOL.BOOL.NonDefault.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataMap.BOOL.BOOL.Unordered.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataMap.BOOL.BOOL.Unordered.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataMap.FIXED32.FIXED32.Default.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataMap.FIXED32.FIXED32.Default.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataMap.FIXED32.FIXED32.DuplicateKey.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataMap.FIXED32.FIXED32.DuplicateKey.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataMap.FIXED32.FIXED32.DuplicateKeyInMapEntry.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataMap.FIXED32.FIXED32.DuplicateKeyInMapEntry.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataMap.FIXED32.FIXED32.DuplicateValueInMapEntry.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataMap.FIXED32.FIXED32.DuplicateValueInMapEntry.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataMap.FIXED32.FIXED32.MissingDefault.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataMap.FIXED32.FIXED32.MissingDefault.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataMap.FIXED32.FIXED32.NonDefault.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataMap.FIXED32.FIXED32.NonDefault.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataMap.FIXED32.FIXED32.Unordered.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataMap.FIXED32.FIXED32.Unordered.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataMap.FIXED64.FIXED64.Default.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataMap.FIXED64.FIXED64.Default.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataMap.FIXED64.FIXED64.DuplicateKey.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataMap.FIXED64.FIXED64.DuplicateKey.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataMap.FIXED64.FIXED64.DuplicateKeyInMapEntry.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataMap.FIXED64.FIXED64.DuplicateKeyInMapEntry.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataMap.FIXED64.FIXED64.DuplicateValueInMapEntry.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataMap.FIXED64.FIXED64.DuplicateValueInMapEntry.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataMap.FIXED64.FIXED64.MissingDefault.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataMap.FIXED64.FIXED64.MissingDefault.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataMap.FIXED64.FIXED64.NonDefault.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataMap.FIXED64.FIXED64.NonDefault.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataMap.FIXED64.FIXED64.Unordered.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataMap.FIXED64.FIXED64.Unordered.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataMap.INT32.DOUBLE.Default.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataMap.INT32.DOUBLE.Default.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataMap.INT32.DOUBLE.DuplicateKey.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataMap.INT32.DOUBLE.DuplicateKey.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataMap.INT32.DOUBLE.DuplicateKeyInMapEntry.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataMap.INT32.DOUBLE.DuplicateKeyInMapEntry.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataMap.INT32.DOUBLE.DuplicateValueInMapEntry.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataMap.INT32.DOUBLE.DuplicateValueInMapEntry.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataMap.INT32.DOUBLE.MissingDefault.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataMap.INT32.DOUBLE.MissingDefault.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataMap.INT32.DOUBLE.NonDefault.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataMap.INT32.DOUBLE.NonDefault.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataMap.INT32.DOUBLE.Unordered.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataMap.INT32.DOUBLE.Unordered.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataMap.INT32.FLOAT.Default.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataMap.INT32.FLOAT.Default.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataMap.INT32.FLOAT.DuplicateKey.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataMap.INT32.FLOAT.DuplicateKey.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataMap.INT32.FLOAT.DuplicateKeyInMapEntry.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataMap.INT32.FLOAT.DuplicateKeyInMapEntry.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataMap.INT32.FLOAT.DuplicateValueInMapEntry.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataMap.INT32.FLOAT.DuplicateValueInMapEntry.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataMap.INT32.FLOAT.MissingDefault.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataMap.INT32.FLOAT.MissingDefault.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataMap.INT32.FLOAT.NonDefault.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataMap.INT32.FLOAT.NonDefault.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataMap.INT32.FLOAT.Unordered.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataMap.INT32.FLOAT.Unordered.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataMap.INT32.INT32.Default.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataMap.INT32.INT32.Default.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataMap.INT32.INT32.DuplicateKey.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataMap.INT32.INT32.DuplicateKey.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataMap.INT32.INT32.DuplicateKeyInMapEntry.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataMap.INT32.INT32.DuplicateKeyInMapEntry.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataMap.INT32.INT32.DuplicateValueInMapEntry.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataMap.INT32.INT32.DuplicateValueInMapEntry.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataMap.INT32.INT32.MissingDefault.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataMap.INT32.INT32.MissingDefault.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataMap.INT32.INT32.NonDefault.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataMap.INT32.INT32.NonDefault.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataMap.INT32.INT32.Unordered.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataMap.INT32.INT32.Unordered.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataMap.INT64.INT64.Default.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataMap.INT64.INT64.Default.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataMap.INT64.INT64.DuplicateKey.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataMap.INT64.INT64.DuplicateKey.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataMap.INT64.INT64.DuplicateKeyInMapEntry.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataMap.INT64.INT64.DuplicateKeyInMapEntry.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataMap.INT64.INT64.DuplicateValueInMapEntry.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataMap.INT64.INT64.DuplicateValueInMapEntry.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataMap.INT64.INT64.MissingDefault.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataMap.INT64.INT64.MissingDefault.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataMap.INT64.INT64.NonDefault.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataMap.INT64.INT64.NonDefault.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataMap.INT64.INT64.Unordered.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataMap.INT64.INT64.Unordered.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataMap.SFIXED32.SFIXED32.Default.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataMap.SFIXED32.SFIXED32.Default.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataMap.SFIXED32.SFIXED32.DuplicateKey.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataMap.SFIXED32.SFIXED32.DuplicateKey.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataMap.SFIXED32.SFIXED32.DuplicateKeyInMapEntry.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataMap.SFIXED32.SFIXED32.DuplicateKeyInMapEntry.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataMap.SFIXED32.SFIXED32.DuplicateValueInMapEntry.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataMap.SFIXED32.SFIXED32.DuplicateValueInMapEntry.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataMap.SFIXED32.SFIXED32.MissingDefault.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataMap.SFIXED32.SFIXED32.MissingDefault.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataMap.SFIXED32.SFIXED32.NonDefault.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataMap.SFIXED32.SFIXED32.NonDefault.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataMap.SFIXED32.SFIXED32.Unordered.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataMap.SFIXED32.SFIXED32.Unordered.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataMap.SFIXED64.SFIXED64.Default.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataMap.SFIXED64.SFIXED64.Default.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataMap.SFIXED64.SFIXED64.DuplicateKey.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataMap.SFIXED64.SFIXED64.DuplicateKey.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataMap.SFIXED64.SFIXED64.DuplicateKeyInMapEntry.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataMap.SFIXED64.SFIXED64.DuplicateKeyInMapEntry.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataMap.SFIXED64.SFIXED64.DuplicateValueInMapEntry.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataMap.SFIXED64.SFIXED64.DuplicateValueInMapEntry.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataMap.SFIXED64.SFIXED64.MissingDefault.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataMap.SFIXED64.SFIXED64.MissingDefault.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataMap.SFIXED64.SFIXED64.NonDefault.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataMap.SFIXED64.SFIXED64.NonDefault.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataMap.SFIXED64.SFIXED64.Unordered.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataMap.SFIXED64.SFIXED64.Unordered.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataMap.SINT32.SINT32.Default.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataMap.SINT32.SINT32.Default.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataMap.SINT32.SINT32.DuplicateKey.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataMap.SINT32.SINT32.DuplicateKey.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataMap.SINT32.SINT32.DuplicateKeyInMapEntry.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataMap.SINT32.SINT32.DuplicateKeyInMapEntry.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataMap.SINT32.SINT32.DuplicateValueInMapEntry.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataMap.SINT32.SINT32.DuplicateValueInMapEntry.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataMap.SINT32.SINT32.MissingDefault.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataMap.SINT32.SINT32.MissingDefault.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataMap.SINT32.SINT32.NonDefault.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataMap.SINT32.SINT32.NonDefault.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataMap.SINT32.SINT32.Unordered.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataMap.SINT32.SINT32.Unordered.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataMap.SINT64.SINT64.Default.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataMap.SINT64.SINT64.Default.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataMap.SINT64.SINT64.DuplicateKey.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataMap.SINT64.SINT64.DuplicateKey.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataMap.SINT64.SINT64.DuplicateKeyInMapEntry.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataMap.SINT64.SINT64.DuplicateKeyInMapEntry.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataMap.SINT64.SINT64.DuplicateValueInMapEntry.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataMap.SINT64.SINT64.DuplicateValueInMapEntry.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataMap.SINT64.SINT64.MissingDefault.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataMap.SINT64.SINT64.MissingDefault.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataMap.SINT64.SINT64.NonDefault.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataMap.SINT64.SINT64.NonDefault.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataMap.SINT64.SINT64.Unordered.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataMap.SINT64.SINT64.Unordered.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataMap.STRING.BYTES.Default.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataMap.STRING.BYTES.Default.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataMap.STRING.BYTES.DuplicateKey.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataMap.STRING.BYTES.DuplicateKey.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataMap.STRING.BYTES.DuplicateKeyInMapEntry.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataMap.STRING.BYTES.DuplicateKeyInMapEntry.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataMap.STRING.BYTES.DuplicateValueInMapEntry.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataMap.STRING.BYTES.DuplicateValueInMapEntry.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataMap.STRING.BYTES.MissingDefault.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataMap.STRING.BYTES.MissingDefault.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataMap.STRING.BYTES.NonDefault.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataMap.STRING.BYTES.NonDefault.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataMap.STRING.BYTES.Unordered.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataMap.STRING.BYTES.Unordered.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataMap.STRING.ENUM.Default.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataMap.STRING.ENUM.Default.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataMap.STRING.ENUM.DuplicateKey.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataMap.STRING.ENUM.DuplicateKey.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataMap.STRING.ENUM.DuplicateKeyInMapEntry.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataMap.STRING.ENUM.DuplicateKeyInMapEntry.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataMap.STRING.ENUM.DuplicateValueInMapEntry.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataMap.STRING.ENUM.DuplicateValueInMapEntry.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataMap.STRING.ENUM.MissingDefault.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataMap.STRING.ENUM.MissingDefault.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataMap.STRING.ENUM.NonDefault.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataMap.STRING.ENUM.NonDefault.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataMap.STRING.ENUM.Unordered.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataMap.STRING.ENUM.Unordered.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataMap.STRING.MESSAGE.Default.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataMap.STRING.MESSAGE.Default.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataMap.STRING.MESSAGE.DuplicateKey.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataMap.STRING.MESSAGE.DuplicateKey.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataMap.STRING.MESSAGE.DuplicateKeyInMapEntry.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataMap.STRING.MESSAGE.DuplicateKeyInMapEntry.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataMap.STRING.MESSAGE.DuplicateValueInMapEntry.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataMap.STRING.MESSAGE.DuplicateValueInMapEntry.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataMap.STRING.MESSAGE.MergeValue.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataMap.STRING.MESSAGE.MergeValue.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataMap.STRING.MESSAGE.MissingDefault.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataMap.STRING.MESSAGE.MissingDefault.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataMap.STRING.MESSAGE.NonDefault.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataMap.STRING.MESSAGE.NonDefault.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataMap.STRING.MESSAGE.Unordered.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataMap.STRING.MESSAGE.Unordered.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataMap.STRING.STRING.Default.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataMap.STRING.STRING.Default.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataMap.STRING.STRING.DuplicateKey.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataMap.STRING.STRING.DuplicateKey.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataMap.STRING.STRING.DuplicateKeyInMapEntry.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataMap.STRING.STRING.DuplicateKeyInMapEntry.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataMap.STRING.STRING.DuplicateValueInMapEntry.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataMap.STRING.STRING.DuplicateValueInMapEntry.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataMap.STRING.STRING.MissingDefault.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataMap.STRING.STRING.MissingDefault.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataMap.STRING.STRING.NonDefault.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataMap.STRING.STRING.NonDefault.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataMap.STRING.STRING.Unordered.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataMap.STRING.STRING.Unordered.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataMap.UINT32.UINT32.Default.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataMap.UINT32.UINT32.Default.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataMap.UINT32.UINT32.DuplicateKey.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataMap.UINT32.UINT32.DuplicateKey.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataMap.UINT32.UINT32.DuplicateKeyInMapEntry.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataMap.UINT32.UINT32.DuplicateKeyInMapEntry.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataMap.UINT32.UINT32.DuplicateValueInMapEntry.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataMap.UINT32.UINT32.DuplicateValueInMapEntry.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataMap.UINT32.UINT32.MissingDefault.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataMap.UINT32.UINT32.MissingDefault.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataMap.UINT32.UINT32.NonDefault.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataMap.UINT32.UINT32.NonDefault.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataMap.UINT32.UINT32.Unordered.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataMap.UINT32.UINT32.Unordered.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataMap.UINT64.UINT64.Default.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataMap.UINT64.UINT64.Default.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataMap.UINT64.UINT64.DuplicateKey.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataMap.UINT64.UINT64.DuplicateKey.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataMap.UINT64.UINT64.DuplicateKeyInMapEntry.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataMap.UINT64.UINT64.DuplicateKeyInMapEntry.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataMap.UINT64.UINT64.DuplicateValueInMapEntry.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataMap.UINT64.UINT64.DuplicateValueInMapEntry.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataMap.UINT64.UINT64.MissingDefault.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataMap.UINT64.UINT64.MissingDefault.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataMap.UINT64.UINT64.NonDefault.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataMap.UINT64.UINT64.NonDefault.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataMap.UINT64.UINT64.Unordered.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataMap.UINT64.UINT64.Unordered.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataOneof.BOOL.DefaultValue.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataOneof.BOOL.DefaultValue.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataOneof.BOOL.MultipleValuesForDifferentField.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataOneof.BOOL.MultipleValuesForDifferentField.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataOneof.BOOL.MultipleValuesForSameField.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataOneof.BOOL.MultipleValuesForSameField.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataOneof.BOOL.NonDefaultValue.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataOneof.BOOL.NonDefaultValue.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataOneof.BYTES.DefaultValue.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataOneof.BYTES.DefaultValue.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataOneof.BYTES.MultipleValuesForDifferentField.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataOneof.BYTES.MultipleValuesForDifferentField.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataOneof.BYTES.MultipleValuesForSameField.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataOneof.BYTES.MultipleValuesForSameField.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataOneof.BYTES.NonDefaultValue.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataOneof.BYTES.NonDefaultValue.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataOneof.DOUBLE.DefaultValue.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataOneof.DOUBLE.DefaultValue.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataOneof.DOUBLE.MultipleValuesForDifferentField.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataOneof.DOUBLE.MultipleValuesForDifferentField.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataOneof.DOUBLE.MultipleValuesForSameField.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataOneof.DOUBLE.MultipleValuesForSameField.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataOneof.DOUBLE.NonDefaultValue.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataOneof.DOUBLE.NonDefaultValue.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataOneof.ENUM.DefaultValue.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataOneof.ENUM.DefaultValue.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataOneof.ENUM.MultipleValuesForDifferentField.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataOneof.ENUM.MultipleValuesForDifferentField.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataOneof.ENUM.MultipleValuesForSameField.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataOneof.ENUM.MultipleValuesForSameField.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataOneof.ENUM.NonDefaultValue.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataOneof.ENUM.NonDefaultValue.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataOneof.FLOAT.DefaultValue.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataOneof.FLOAT.DefaultValue.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataOneof.FLOAT.MultipleValuesForDifferentField.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataOneof.FLOAT.MultipleValuesForDifferentField.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataOneof.FLOAT.MultipleValuesForSameField.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataOneof.FLOAT.MultipleValuesForSameField.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataOneof.FLOAT.NonDefaultValue.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataOneof.FLOAT.NonDefaultValue.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataOneof.MESSAGE.DefaultValue.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataOneof.MESSAGE.DefaultValue.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataOneof.MESSAGE.Merge.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataOneof.MESSAGE.Merge.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataOneof.MESSAGE.MultipleValuesForDifferentField.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataOneof.MESSAGE.MultipleValuesForDifferentField.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataOneof.MESSAGE.MultipleValuesForSameField.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataOneof.MESSAGE.MultipleValuesForSameField.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataOneof.MESSAGE.NonDefaultValue.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataOneof.MESSAGE.NonDefaultValue.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataOneof.STRING.DefaultValue.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataOneof.STRING.DefaultValue.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataOneof.STRING.MultipleValuesForDifferentField.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataOneof.STRING.MultipleValuesForDifferentField.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataOneof.STRING.MultipleValuesForSameField.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataOneof.STRING.MultipleValuesForSameField.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataOneof.STRING.NonDefaultValue.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataOneof.STRING.NonDefaultValue.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataOneof.UINT32.DefaultValue.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataOneof.UINT32.DefaultValue.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataOneof.UINT32.MultipleValuesForDifferentField.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataOneof.UINT32.MultipleValuesForDifferentField.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataOneof.UINT32.MultipleValuesForSameField.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataOneof.UINT32.MultipleValuesForSameField.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataOneof.UINT32.NonDefaultValue.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataOneof.UINT32.NonDefaultValue.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataOneof.UINT64.DefaultValue.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataOneof.UINT64.DefaultValue.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataOneof.UINT64.MultipleValuesForDifferentField.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataOneof.UINT64.MultipleValuesForDifferentField.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataOneof.UINT64.MultipleValuesForSameField.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataOneof.UINT64.MultipleValuesForSameField.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataOneof.UINT64.NonDefaultValue.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataOneof.UINT64.NonDefaultValue.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataRepeated.BOOL.PackedInput.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataRepeated.BOOL.PackedInput.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataRepeated.BOOL.UnpackedInput.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataRepeated.BOOL.UnpackedInput.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataRepeated.BYTES.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataRepeated.BYTES.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataRepeated.DOUBLE.PackedInput.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataRepeated.DOUBLE.PackedInput.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataRepeated.DOUBLE.UnpackedInput.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataRepeated.DOUBLE.UnpackedInput.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataRepeated.ENUM.PackedInput.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataRepeated.ENUM.PackedInput.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataRepeated.ENUM.UnpackedInput.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataRepeated.ENUM.UnpackedInput.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataRepeated.FIXED32.PackedInput.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataRepeated.FIXED32.PackedInput.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataRepeated.FIXED32.UnpackedInput.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataRepeated.FIXED32.UnpackedInput.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataRepeated.FIXED64.PackedInput.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataRepeated.FIXED64.PackedInput.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataRepeated.FIXED64.UnpackedInput.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataRepeated.FIXED64.UnpackedInput.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataRepeated.FLOAT.PackedInput.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataRepeated.FLOAT.PackedInput.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataRepeated.FLOAT.UnpackedInput.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataRepeated.FLOAT.UnpackedInput.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataRepeated.INT32.PackedInput.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataRepeated.INT32.PackedInput.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataRepeated.INT32.UnpackedInput.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataRepeated.INT32.UnpackedInput.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataRepeated.INT64.PackedInput.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataRepeated.INT64.PackedInput.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataRepeated.INT64.UnpackedInput.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataRepeated.INT64.UnpackedInput.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataRepeated.MESSAGE.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataRepeated.MESSAGE.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataRepeated.SFIXED32.PackedInput.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataRepeated.SFIXED32.PackedInput.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataRepeated.SFIXED32.UnpackedInput.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataRepeated.SFIXED32.UnpackedInput.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataRepeated.SFIXED64.PackedInput.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataRepeated.SFIXED64.PackedInput.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataRepeated.SFIXED64.UnpackedInput.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataRepeated.SFIXED64.UnpackedInput.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataRepeated.SINT32.PackedInput.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataRepeated.SINT32.PackedInput.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataRepeated.SINT32.UnpackedInput.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataRepeated.SINT32.UnpackedInput.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataRepeated.SINT64.PackedInput.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataRepeated.SINT64.PackedInput.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataRepeated.SINT64.UnpackedInput.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataRepeated.SINT64.UnpackedInput.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataRepeated.STRING.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataRepeated.STRING.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataRepeated.UINT32.PackedInput.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataRepeated.UINT32.PackedInput.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataRepeated.UINT32.UnpackedInput.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataRepeated.UINT32.UnpackedInput.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataRepeated.UINT64.PackedInput.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataRepeated.UINT64.PackedInput.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataRepeated.UINT64.UnpackedInput.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataRepeated.UINT64.UnpackedInput.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataScalar.BOOL[2].JsonOutput
-Required.Proto3.ProtobufInput.ValidDataScalar.BOOL[2].ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataScalar.BOOL[3].JsonOutput
-Required.Proto3.ProtobufInput.ValidDataScalar.BOOL[3].ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataScalar.BOOL[4].JsonOutput
-Required.Proto3.ProtobufInput.ValidDataScalar.BOOL[4].ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataScalar.BOOL[5].JsonOutput
-Required.Proto3.ProtobufInput.ValidDataScalar.BOOL[5].ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataScalar.BOOL[6].JsonOutput
-Required.Proto3.ProtobufInput.ValidDataScalar.BOOL[6].ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataScalar.BYTES[3].JsonOutput
-Required.Proto3.ProtobufInput.ValidDataScalar.BYTES[3].ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataScalar.DOUBLE[1].JsonOutput
-Required.Proto3.ProtobufInput.ValidDataScalar.DOUBLE[1].ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataScalar.DOUBLE[2].JsonOutput
-Required.Proto3.ProtobufInput.ValidDataScalar.DOUBLE[2].ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataScalar.ENUM[0].JsonOutput
-Required.Proto3.ProtobufInput.ValidDataScalar.ENUM[0].ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataScalar.ENUM[1].JsonOutput
-Required.Proto3.ProtobufInput.ValidDataScalar.ENUM[1].ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataScalar.ENUM[2].JsonOutput
-Required.Proto3.ProtobufInput.ValidDataScalar.ENUM[2].ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataScalar.ENUM[3].JsonOutput
-Required.Proto3.ProtobufInput.ValidDataScalar.ENUM[3].ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataScalar.ENUM[4].JsonOutput
-Required.Proto3.ProtobufInput.ValidDataScalar.ENUM[4].ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataScalar.ENUM[5].JsonOutput
-Required.Proto3.ProtobufInput.ValidDataScalar.ENUM[5].ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataScalar.FIXED32[2].JsonOutput
-Required.Proto3.ProtobufInput.ValidDataScalar.FIXED32[2].ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataScalar.FIXED64[2].JsonOutput
-Required.Proto3.ProtobufInput.ValidDataScalar.FIXED64[2].ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataScalar.FLOAT[1].JsonOutput
-Required.Proto3.ProtobufInput.ValidDataScalar.FLOAT[1].ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataScalar.FLOAT[2].JsonOutput
-Required.Proto3.ProtobufInput.ValidDataScalar.FLOAT[2].ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataScalar.FLOAT[3].JsonOutput
-Required.Proto3.ProtobufInput.ValidDataScalar.FLOAT[3].ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataScalar.FLOAT[4].JsonOutput
-Required.Proto3.ProtobufInput.ValidDataScalar.FLOAT[4].ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataScalar.INT32[1].JsonOutput
-Required.Proto3.ProtobufInput.ValidDataScalar.INT32[1].ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataScalar.INT32[2].JsonOutput
-Required.Proto3.ProtobufInput.ValidDataScalar.INT32[2].ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataScalar.INT32[3].JsonOutput
-Required.Proto3.ProtobufInput.ValidDataScalar.INT32[3].ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataScalar.INT32[4].JsonOutput
-Required.Proto3.ProtobufInput.ValidDataScalar.INT32[4].ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataScalar.INT32[5].JsonOutput
-Required.Proto3.ProtobufInput.ValidDataScalar.INT32[5].ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataScalar.INT32[6].JsonOutput
-Required.Proto3.ProtobufInput.ValidDataScalar.INT32[6].ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataScalar.INT32[7].JsonOutput
-Required.Proto3.ProtobufInput.ValidDataScalar.INT32[7].ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataScalar.INT32[8].JsonOutput
-Required.Proto3.ProtobufInput.ValidDataScalar.INT32[8].ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataScalar.INT32[9].JsonOutput
-Required.Proto3.ProtobufInput.ValidDataScalar.INT32[9].ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataScalar.INT64[1].JsonOutput
-Required.Proto3.ProtobufInput.ValidDataScalar.INT64[1].ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataScalar.INT64[2].JsonOutput
-Required.Proto3.ProtobufInput.ValidDataScalar.INT64[2].ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataScalar.INT64[3].JsonOutput
-Required.Proto3.ProtobufInput.ValidDataScalar.INT64[3].ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataScalar.MESSAGE[0].JsonOutput
-Required.Proto3.ProtobufInput.ValidDataScalar.MESSAGE[0].ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataScalar.MESSAGE[1].JsonOutput
-Required.Proto3.ProtobufInput.ValidDataScalar.MESSAGE[1].ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataScalar.SFIXED32[2].JsonOutput
-Required.Proto3.ProtobufInput.ValidDataScalar.SFIXED32[2].ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataScalar.SFIXED32[3].JsonOutput
-Required.Proto3.ProtobufInput.ValidDataScalar.SFIXED32[3].ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataScalar.SFIXED64[2].JsonOutput
-Required.Proto3.ProtobufInput.ValidDataScalar.SFIXED64[2].ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataScalar.SFIXED64[3].JsonOutput
-Required.Proto3.ProtobufInput.ValidDataScalar.SFIXED64[3].ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataScalar.SINT32[1].JsonOutput
-Required.Proto3.ProtobufInput.ValidDataScalar.SINT32[1].ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataScalar.SINT32[2].JsonOutput
-Required.Proto3.ProtobufInput.ValidDataScalar.SINT32[2].ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataScalar.SINT32[3].JsonOutput
-Required.Proto3.ProtobufInput.ValidDataScalar.SINT32[3].ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataScalar.SINT32[4].JsonOutput
-Required.Proto3.ProtobufInput.ValidDataScalar.SINT32[4].ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataScalar.SINT64[1].JsonOutput
-Required.Proto3.ProtobufInput.ValidDataScalar.SINT64[1].ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataScalar.SINT64[2].JsonOutput
-Required.Proto3.ProtobufInput.ValidDataScalar.SINT64[2].ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataScalar.SINT64[3].JsonOutput
-Required.Proto3.ProtobufInput.ValidDataScalar.SINT64[3].ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataScalar.STRING[3].JsonOutput
-Required.Proto3.ProtobufInput.ValidDataScalar.STRING[3].ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataScalar.STRING[4].JsonOutput
-Required.Proto3.ProtobufInput.ValidDataScalar.STRING[4].ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataScalar.STRING[5].JsonOutput
-Required.Proto3.ProtobufInput.ValidDataScalar.STRING[5].ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataScalar.STRING[6].JsonOutput
-Required.Proto3.ProtobufInput.ValidDataScalar.STRING[6].ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataScalar.UINT32[1].JsonOutput
-Required.Proto3.ProtobufInput.ValidDataScalar.UINT32[1].ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataScalar.UINT32[2].JsonOutput
-Required.Proto3.ProtobufInput.ValidDataScalar.UINT32[2].ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataScalar.UINT32[3].JsonOutput
-Required.Proto3.ProtobufInput.ValidDataScalar.UINT32[3].ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataScalar.UINT32[4].JsonOutput
-Required.Proto3.ProtobufInput.ValidDataScalar.UINT32[4].ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataScalar.UINT32[5].JsonOutput
-Required.Proto3.ProtobufInput.ValidDataScalar.UINT32[5].ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataScalar.UINT32[6].JsonOutput
-Required.Proto3.ProtobufInput.ValidDataScalar.UINT32[6].ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataScalar.UINT32[7].JsonOutput
-Required.Proto3.ProtobufInput.ValidDataScalar.UINT32[7].ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataScalar.UINT32[8].JsonOutput
-Required.Proto3.ProtobufInput.ValidDataScalar.UINT32[8].ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataScalar.UINT32[9].JsonOutput
-Required.Proto3.ProtobufInput.ValidDataScalar.UINT32[9].ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataScalar.UINT64[1].JsonOutput
-Required.Proto3.ProtobufInput.ValidDataScalar.UINT64[1].ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataScalar.UINT64[2].JsonOutput
-Required.Proto3.ProtobufInput.ValidDataScalar.UINT64[2].ProtobufOutput
-Required.TimestampProtoInputTooLarge.JsonOutput
-Required.TimestampProtoInputTooSmall.JsonOutput
diff --git a/csharp/Google.Protobuf.Tools.nuspec b/csharp/Google.Protobuf.Tools.nuspec
index cca07ba..11b6618 100644
--- a/csharp/Google.Protobuf.Tools.nuspec
+++ b/csharp/Google.Protobuf.Tools.nuspec
@@ -5,7 +5,7 @@
     <title>Google Protocol Buffers tools</title>
     <summary>Tools for Protocol Buffers - Google's data interchange format.</summary>
     <description>See project site for more info.</description>
-    <version>3.17.3</version>
+    <version>3.18.0</version>
     <authors>Google Inc.</authors>
     <owners>protobuf-packages</owners>
     <licenseUrl>https://github.com/protocolbuffers/protobuf/blob/master/LICENSE</licenseUrl>
diff --git a/csharp/src/Google.Protobuf/Google.Protobuf.csproj b/csharp/src/Google.Protobuf/Google.Protobuf.csproj
index 41b2b64..c5996a5 100644
--- a/csharp/src/Google.Protobuf/Google.Protobuf.csproj
+++ b/csharp/src/Google.Protobuf/Google.Protobuf.csproj
@@ -4,7 +4,7 @@
     <Description>C# runtime library for Protocol Buffers - Google's data interchange format.</Description>
     <Copyright>Copyright 2015, Google Inc.</Copyright>
     <AssemblyTitle>Google Protocol Buffers</AssemblyTitle>
-    <VersionPrefix>3.17.3</VersionPrefix>
+    <VersionPrefix>3.18.0</VersionPrefix>
     <!-- C# 7.2 is required for Span/BufferWriter/ReadOnlySequence -->
     <LangVersion>7.2</LangVersion>
     <Authors>Google Inc.</Authors>
diff --git a/docs/options.md b/docs/options.md
index 28ae104..159951a 100644
--- a/docs/options.md
+++ b/docs/options.md
@@ -205,7 +205,7 @@
    * Website: https://github.com/envoyproxy/protoc-gen-validate
    * Extensions: 1071
 
-1. protokt
+1. Protokt
    * Website: https://github.com/open-toast/protokt
    * Extensions: 1072
 
@@ -291,4 +291,4 @@
 
 1. Protoc-gen-jsonschema
    * Website: https://github.com/chrusty/protoc-gen-jsonschema
-   * Extension: 1125
+   * Extension: 1125-1129
diff --git a/docs/third_party.md b/docs/third_party.md
index 4075327..ca2ac63 100644
--- a/docs/third_party.md
+++ b/docs/third_party.md
@@ -70,6 +70,7 @@
 * Kotlin: https://github.com/marcoferrer/kroto-plus
 * Kotlin: https://github.com/Kotlin/kotlinx.serialization
 * Kotlin: https://github.com/ButterCam/sisyphus
+* Kotlin: https://github.com/open-toast/protokt
 * Lua: http://code.google.com/p/protoc-gen-lua/
 * Lua: http://github.com/indygreg/lua-protobuf
 * Lua: https://github.com/Neopallium/lua-pb
diff --git a/java/bom/pom.xml b/java/bom/pom.xml
index 5cf9774..6b624ec 100644
--- a/java/bom/pom.xml
+++ b/java/bom/pom.xml
@@ -4,7 +4,7 @@
 
   <groupId>com.google.protobuf</groupId>
   <artifactId>protobuf-bom</artifactId>
-  <version>3.17.3</version>
+  <version>3.18.0</version>
   <packaging>pom</packaging>
 
   <name>Protocol Buffers [BOM]</name>
diff --git a/java/core/BUILD b/java/core/BUILD
index 9308ba7..8ac355e 100644
--- a/java/core/BUILD
+++ b/java/core/BUILD
@@ -21,6 +21,8 @@
     "src/main/java/com/google/protobuf/ByteBufferWriter.java",
     "src/main/java/com/google/protobuf/ByteOutput.java",
     "src/main/java/com/google/protobuf/ByteString.java",
+    "src/main/java/com/google/protobuf/CanIgnoreReturnValue.java",
+    "src/main/java/com/google/protobuf/CheckReturnValue.java",
     "src/main/java/com/google/protobuf/CodedInputStream.java",
     "src/main/java/com/google/protobuf/CodedInputStreamReader.java",
     "src/main/java/com/google/protobuf/CodedOutputStream.java",
diff --git a/java/core/pom.xml b/java/core/pom.xml
index 468ab48..bf185b0 100644
--- a/java/core/pom.xml
+++ b/java/core/pom.xml
@@ -4,7 +4,7 @@
   <parent>
     <groupId>com.google.protobuf</groupId>
     <artifactId>protobuf-parent</artifactId>
-    <version>3.17.3</version>
+    <version>3.18.0</version>
   </parent>
 
   <artifactId>protobuf-java</artifactId>
diff --git a/java/core/src/main/java/com/google/protobuf/ByteString.java b/java/core/src/main/java/com/google/protobuf/ByteString.java
index 68e3044..a4beaeb 100644
--- a/java/core/src/main/java/com/google/protobuf/ByteString.java
+++ b/java/core/src/main/java/com/google/protobuf/ByteString.java
@@ -73,6 +73,7 @@
  * @author [email protected] Carl Haverl
  * @author [email protected] Martin Buchholz
  */
+@CheckReturnValue
 public abstract class ByteString implements Iterable<Byte>, Serializable {
 
   /**
@@ -1275,6 +1276,7 @@
    * @return the length of the range.
    * @throws IndexOutOfBoundsException some or all of the range falls outside of the array.
    */
+  @CanIgnoreReturnValue
   static int checkRange(int startIndex, int endIndex, int size) {
     final int length = endIndex - startIndex;
     if ((startIndex | endIndex | length | (size - endIndex)) < 0) {
diff --git a/java/core/src/main/java/com/google/protobuf/CanIgnoreReturnValue.java b/java/core/src/main/java/com/google/protobuf/CanIgnoreReturnValue.java
new file mode 100644
index 0000000..9e84432
--- /dev/null
+++ b/java/core/src/main/java/com/google/protobuf/CanIgnoreReturnValue.java
@@ -0,0 +1,50 @@
+// 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.
+
+package com.google.protobuf;
+
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.TYPE;
+import static java.lang.annotation.RetentionPolicy.CLASS;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+/**
+ * Indicates that the return value of the annotated method can be safely ignored.
+ *
+ * <p>This is the opposite of {@link CheckReturnValue}. It can be used inside classes or packages
+ * annotated with {@code @CheckReturnValue} to exempt specific methods from the default.
+ */
+@Documented
+@Target({METHOD, TYPE})
+@Retention(CLASS)
+@interface CanIgnoreReturnValue {}
diff --git a/java/core/src/main/java/com/google/protobuf/CheckReturnValue.java b/java/core/src/main/java/com/google/protobuf/CheckReturnValue.java
new file mode 100644
index 0000000..38c83d8
--- /dev/null
+++ b/java/core/src/main/java/com/google/protobuf/CheckReturnValue.java
@@ -0,0 +1,55 @@
+// 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.
+
+package com.google.protobuf;
+
+import static java.lang.annotation.ElementType.CONSTRUCTOR;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.PACKAGE;
+import static java.lang.annotation.ElementType.TYPE;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+/**
+ * Indicates that the return value of the annotated method must be checked. An error is triggered
+ * when one of these methods is called but the result is not used.
+ *
+ * <p>{@code @CheckReturnValue} may be applied to a class or package to indicate that all methods in
+ * that class or package must have their return values checked. For convenience, we provide an
+ * annotation, {@link CanIgnoreReturnValue}, to exempt specific methods or classes from this
+ * behavior.
+ */
+@Documented
+@Target({METHOD, CONSTRUCTOR, TYPE, PACKAGE})
+@Retention(RUNTIME)
+@interface CheckReturnValue {}
diff --git a/java/core/src/main/java/com/google/protobuf/Descriptors.java b/java/core/src/main/java/com/google/protobuf/Descriptors.java
index 7b14584..eb690b5 100644
--- a/java/core/src/main/java/com/google/protobuf/Descriptors.java
+++ b/java/core/src/main/java/com/google/protobuf/Descriptors.java
@@ -53,8 +53,9 @@
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
+import java.util.Comparator;
 import java.util.HashMap;
-import java.util.HashSet;
+import java.util.IdentityHashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
@@ -79,6 +80,13 @@
  */
 public final class Descriptors {
   private static final Logger logger = Logger.getLogger(Descriptors.class.getName());
+  private static final int[] EMPTY_INT_ARRAY = new int[0];
+  private static final Descriptor[] EMPTY_DESCRIPTORS = new Descriptor[0];
+  private static final FieldDescriptor[] EMPTY_FIELD_DESCRIPTORS = new FieldDescriptor[0];
+  private static final EnumDescriptor[] EMPTY_ENUM_DESCRIPTORS = new EnumDescriptor[0];
+  private static final ServiceDescriptor[] EMPTY_SERVICE_DESCRIPTORS = new ServiceDescriptor[0];
+  private static final OneofDescriptor[] EMPTY_ONEOF_DESCRIPTORS = new OneofDescriptor[0];
+
   /**
    * Describes a {@code .proto} file, including everything defined within. That includes, in
    * particular, descriptors for all the messages and file descriptors for all other imported {@code
@@ -401,8 +409,7 @@
      * except that the {@code FileDescriptorProto} is encoded in protocol buffer wire format.
      */
     public static FileDescriptor internalBuildGeneratedFileFrom(
-        final String[] descriptorDataParts,
-        final FileDescriptor[] dependencies) {
+        final String[] descriptorDataParts, final FileDescriptor[] dependencies) {
       final byte[] descriptorBytes = latin1Cat(descriptorDataParts);
 
       FileDescriptorProto proto;
@@ -434,10 +441,9 @@
         final String[] dependencyClassNames,
         final String[] dependencyFileNames,
         final InternalDescriptorAssigner descriptorAssigner) {
-      FileDescriptor[] dependencies = findDescriptors(
-          descriptorOuterClass, dependencyClassNames, dependencyFileNames);
-      internalBuildGeneratedFileFrom(
-          descriptorDataParts, dependencies, descriptorAssigner);
+      FileDescriptor[] dependencies =
+          findDescriptors(descriptorOuterClass, dependencyClassNames, dependencyFileNames);
+      internalBuildGeneratedFileFrom(descriptorDataParts, dependencies, descriptorAssigner);
     }
 
     /**
@@ -449,8 +455,8 @@
         final Class<?> descriptorOuterClass,
         final String[] dependencyClassNames,
         final String[] dependencyFileNames) {
-      FileDescriptor[] dependencies = findDescriptors(
-          descriptorOuterClass, dependencyClassNames, dependencyFileNames);
+      FileDescriptor[] dependencies =
+          findDescriptors(descriptorOuterClass, dependencyClassNames, dependencyFileNames);
       return internalBuildGeneratedFileFrom(descriptorDataParts, dependencies);
     }
 
@@ -482,7 +488,8 @@
      * "Options" messages defined in descriptor.proto. The callback may also return null to indicate
      * that no extensions are used in the descriptor.
      *
-     * This interface is deprecated.  Use the return value of internalBuildGeneratedFrom() instead.
+     * <p>This interface is deprecated. Use the return value of internalBuildGeneratedFrom()
+     * instead.
      */
     @Deprecated
     public interface InternalDescriptorAssigner {
@@ -533,22 +540,34 @@
 
       pool.addPackage(getPackage(), this);
 
-      messageTypes = new Descriptor[proto.getMessageTypeCount()];
+      messageTypes =
+          (proto.getMessageTypeCount() > 0)
+              ? new Descriptor[proto.getMessageTypeCount()]
+              : EMPTY_DESCRIPTORS;
       for (int i = 0; i < proto.getMessageTypeCount(); i++) {
         messageTypes[i] = new Descriptor(proto.getMessageType(i), this, null, i);
       }
 
-      enumTypes = new EnumDescriptor[proto.getEnumTypeCount()];
+      enumTypes =
+          (proto.getEnumTypeCount() > 0)
+              ? new EnumDescriptor[proto.getEnumTypeCount()]
+              : EMPTY_ENUM_DESCRIPTORS;
       for (int i = 0; i < proto.getEnumTypeCount(); i++) {
         enumTypes[i] = new EnumDescriptor(proto.getEnumType(i), this, null, i);
       }
 
-      services = new ServiceDescriptor[proto.getServiceCount()];
+      services =
+          (proto.getServiceCount() > 0)
+              ? new ServiceDescriptor[proto.getServiceCount()]
+              : EMPTY_SERVICE_DESCRIPTORS;
       for (int i = 0; i < proto.getServiceCount(); i++) {
         services[i] = new ServiceDescriptor(proto.getService(i), this, i);
       }
 
-      extensions = new FieldDescriptor[proto.getExtensionCount()];
+      extensions =
+          (proto.getExtensionCount() > 0)
+              ? new FieldDescriptor[proto.getExtensionCount()]
+              : EMPTY_FIELD_DESCRIPTORS;
       for (int i = 0; i < proto.getExtensionCount(); i++) {
         extensions[i] = new FieldDescriptor(proto.getExtension(i), this, null, i, true);
       }
@@ -567,9 +586,9 @@
       this.publicDependencies = new FileDescriptor[0];
 
       messageTypes = new Descriptor[] {message};
-      enumTypes = new EnumDescriptor[0];
-      services = new ServiceDescriptor[0];
-      extensions = new FieldDescriptor[0];
+      enumTypes = EMPTY_ENUM_DESCRIPTORS;
+      services = EMPTY_SERVICE_DESCRIPTORS;
+      extensions = EMPTY_FIELD_DESCRIPTORS;
 
       pool.addPackage(packageName, this);
       pool.addSymbol(message);
@@ -767,7 +786,9 @@
      * @param name The unqualified name of the field (e.g. "foo"). For protocol buffer messages that
      *     follow <a
      *     href=https://developers.google.com/protocol-buffers/docs/style#message_and_field_names>Google's
-     *     guidance on naming</a> this will be a snake case string, such as <pre>song_name</pre>.
+     *     guidance on naming</a> this will be a snake case string, such as
+     *     <pre>song_name</pre>
+     *     .
      * @return The field's descriptor, or {@code null} if not found.
      */
     public FieldDescriptor findFieldByName(final String name) {
@@ -786,7 +807,8 @@
      * @return The field's descriptor, or {@code null} if not found.
      */
     public FieldDescriptor findFieldByNumber(final int number) {
-      return file.pool.fieldsByNumber.get(new DescriptorPool.DescriptorIntPair(this, number));
+      return binarySearch(
+          fieldsSortedByNumber, fieldsSortedByNumber.length, FieldDescriptor.NUMBER_GETTER, number);
     }
 
     /**
@@ -827,6 +849,7 @@
     private final Descriptor[] nestedTypes;
     private final EnumDescriptor[] enumTypes;
     private final FieldDescriptor[] fields;
+    private final FieldDescriptor[] fieldsSortedByNumber;
     private final FieldDescriptor[] extensions;
     private final OneofDescriptor[] oneofs;
     private final int realOneofCount;
@@ -853,11 +876,12 @@
       this.fullName = fullname;
       this.containingType = null;
 
-      this.nestedTypes = new Descriptor[0];
-      this.enumTypes = new EnumDescriptor[0];
-      this.fields = new FieldDescriptor[0];
-      this.extensions = new FieldDescriptor[0];
-      this.oneofs = new OneofDescriptor[0];
+      this.nestedTypes = EMPTY_DESCRIPTORS;
+      this.enumTypes = EMPTY_ENUM_DESCRIPTORS;
+      this.fields = EMPTY_FIELD_DESCRIPTORS;
+      this.fieldsSortedByNumber = EMPTY_FIELD_DESCRIPTORS;
+      this.extensions = EMPTY_FIELD_DESCRIPTORS;
+      this.oneofs = EMPTY_ONEOF_DESCRIPTORS;
       this.realOneofCount = 0;
 
       // Create a placeholder FileDescriptor to hold this message.
@@ -879,27 +903,44 @@
       this.file = file;
       containingType = parent;
 
-      oneofs = new OneofDescriptor[proto.getOneofDeclCount()];
+      oneofs =
+          (proto.getOneofDeclCount() > 0)
+              ? new OneofDescriptor[proto.getOneofDeclCount()]
+              : EMPTY_ONEOF_DESCRIPTORS;
       for (int i = 0; i < proto.getOneofDeclCount(); i++) {
         oneofs[i] = new OneofDescriptor(proto.getOneofDecl(i), file, this, i);
       }
 
-      nestedTypes = new Descriptor[proto.getNestedTypeCount()];
+      nestedTypes =
+          (proto.getNestedTypeCount() > 0)
+              ? new Descriptor[proto.getNestedTypeCount()]
+              : EMPTY_DESCRIPTORS;
       for (int i = 0; i < proto.getNestedTypeCount(); i++) {
         nestedTypes[i] = new Descriptor(proto.getNestedType(i), file, this, i);
       }
 
-      enumTypes = new EnumDescriptor[proto.getEnumTypeCount()];
+      enumTypes =
+          (proto.getEnumTypeCount() > 0)
+              ? new EnumDescriptor[proto.getEnumTypeCount()]
+              : EMPTY_ENUM_DESCRIPTORS;
       for (int i = 0; i < proto.getEnumTypeCount(); i++) {
         enumTypes[i] = new EnumDescriptor(proto.getEnumType(i), file, this, i);
       }
 
-      fields = new FieldDescriptor[proto.getFieldCount()];
+      fields =
+          (proto.getFieldCount() > 0)
+              ? new FieldDescriptor[proto.getFieldCount()]
+              : EMPTY_FIELD_DESCRIPTORS;
       for (int i = 0; i < proto.getFieldCount(); i++) {
         fields[i] = new FieldDescriptor(proto.getField(i), file, this, i, false);
       }
+      this.fieldsSortedByNumber =
+          (proto.getFieldCount() > 0) ? fields.clone() : EMPTY_FIELD_DESCRIPTORS;
 
-      extensions = new FieldDescriptor[proto.getExtensionCount()];
+      extensions =
+          (proto.getExtensionCount() > 0)
+              ? new FieldDescriptor[proto.getExtensionCount()]
+              : EMPTY_FIELD_DESCRIPTORS;
       for (int i = 0; i < proto.getExtensionCount(); i++) {
         extensions[i] = new FieldDescriptor(proto.getExtension(i), file, this, i, true);
       }
@@ -930,18 +971,23 @@
       file.pool.addSymbol(this);
 
       // NOTE: The defined extension ranges are guaranteed to be disjoint.
-      extensionRangeLowerBounds = new int[proto.getExtensionRangeCount()];
-      extensionRangeUpperBounds = new int[proto.getExtensionRangeCount()];
-      int i = 0;
-      for (final DescriptorProto.ExtensionRange range : proto.getExtensionRangeList()) {
-        extensionRangeLowerBounds[i] = range.getStart();
-        extensionRangeUpperBounds[i] = range.getEnd();
-        i++;
+      if (proto.getExtensionRangeCount() > 0) {
+        extensionRangeLowerBounds = new int[proto.getExtensionRangeCount()];
+        extensionRangeUpperBounds = new int[proto.getExtensionRangeCount()];
+        int i = 0;
+        for (final DescriptorProto.ExtensionRange range : proto.getExtensionRangeList()) {
+          extensionRangeLowerBounds[i] = range.getStart();
+          extensionRangeUpperBounds[i] = range.getEnd();
+          i++;
+        }
+        // Since the ranges are disjoint, sorting these independently must still produce the correct
+        // order.
+        Arrays.sort(extensionRangeLowerBounds);
+        Arrays.sort(extensionRangeUpperBounds);
+      } else {
+        extensionRangeLowerBounds = EMPTY_INT_ARRAY;
+        extensionRangeUpperBounds = EMPTY_INT_ARRAY;
       }
-      // Since the ranges are disjoint, sorting these independently must still produce the correct
-      // order.
-      Arrays.sort(extensionRangeLowerBounds);
-      Arrays.sort(extensionRangeUpperBounds);
     }
 
     /** Look up and cross-link all field types, etc. */
@@ -953,12 +999,32 @@
       for (final FieldDescriptor field : fields) {
         field.crossLink();
       }
+      Arrays.sort(fieldsSortedByNumber);
+      validateNoDuplicateFieldNumbers();
 
       for (final FieldDescriptor extension : extensions) {
         extension.crossLink();
       }
     }
 
+    private void validateNoDuplicateFieldNumbers() throws DescriptorValidationException {
+      for (int i = 0; i + 1 < fieldsSortedByNumber.length; i++) {
+        FieldDescriptor old = fieldsSortedByNumber[i];
+        FieldDescriptor field = fieldsSortedByNumber[i + 1];
+        if (old.getNumber() == field.getNumber()) {
+          throw new DescriptorValidationException(
+              field,
+              "Field number "
+                  + field.getNumber()
+                  + " has already been used in \""
+                  + field.getContainingType().getFullName()
+                  + "\" by field \""
+                  + old.getName()
+                  + "\".");
+        }
+      }
+    }
+
     /** See {@link FileDescriptor#setProto}. */
     private void setProto(final DescriptorProto proto) {
       this.proto = proto;
@@ -990,6 +1056,14 @@
   /** Describes a field of a message type. */
   public static final class FieldDescriptor extends GenericDescriptor
       implements Comparable<FieldDescriptor>, FieldSet.FieldDescriptorLite<FieldDescriptor> {
+    private static final NumberGetter<FieldDescriptor> NUMBER_GETTER =
+        new NumberGetter<FieldDescriptor>() {
+          @Override
+          public int getNumber(FieldDescriptor fieldDescriptor) {
+            return fieldDescriptor.getNumber();
+          }
+        };
+
     /**
      * Get the index of this descriptor within its parent.
      *
@@ -1029,7 +1103,14 @@
 
     /** Get the JSON name of this field. */
     public String getJsonName() {
-      return jsonName;
+      String result = jsonName;
+      if (result != null) {
+        return result;
+      } else if (proto.hasJsonName()) {
+        return jsonName = proto.getJsonName();
+      } else {
+        return jsonName = fieldNameToJsonName(proto.getName());
+      }
     }
 
     /**
@@ -1191,7 +1272,7 @@
      * <p>For fields where hasPresence() == true, the return value of msg.hasField() is semantically
      * meaningful.
      */
-    boolean hasPresence() {
+    public boolean hasPresence() {
       if (isRepeated()) {
         return false;
       }
@@ -1276,7 +1357,7 @@
 
     private FieldDescriptorProto proto;
     private final String fullName;
-    private final String jsonName;
+    private String jsonName;
     private final FileDescriptor file;
     private final Descriptor extensionScope;
     private final boolean isProto3Optional;
@@ -1397,11 +1478,6 @@
       this.proto = proto;
       fullName = computeFullName(file, parent, proto.getName());
       this.file = file;
-      if (proto.hasJsonName()) {
-        jsonName = proto.getJsonName();
-      } else {
-        jsonName = fieldNameToJsonName(proto.getName());
-      }
 
       if (proto.hasType()) {
         type = Type.valueOf(proto.getType());
@@ -1627,10 +1703,6 @@
         }
       }
 
-      if (!isExtension()) {
-        file.pool.addFieldByNumber(this);
-      }
-
       if (containingType != null && containingType.getOptions().getMessageSetWireFormat()) {
         if (isExtension()) {
           if (!isOptional() || getType() != Type.MESSAGE) {
@@ -1740,7 +1812,8 @@
      */
     @Override
     public EnumValueDescriptor findValueByNumber(final int number) {
-      return file.pool.enumValuesByNumber.get(new DescriptorPool.DescriptorIntPair(this, number));
+      return binarySearch(
+          valuesSortedByNumber, distinctNumbers, EnumValueDescriptor.NUMBER_GETTER, number);
     }
 
     /**
@@ -1789,7 +1862,7 @@
           result = reference.get();
         }
         if (result == null) {
-          result = new EnumValueDescriptor(file, this, key);
+          result = new EnumValueDescriptor(this, key);
           unknownValues.put(key, new WeakReference<EnumValueDescriptor>(result));
         }
       }
@@ -1806,7 +1879,9 @@
     private final String fullName;
     private final FileDescriptor file;
     private final Descriptor containingType;
-    private EnumValueDescriptor[] values;
+    private final EnumValueDescriptor[] values;
+    private final EnumValueDescriptor[] valuesSortedByNumber;
+    private final int distinctNumbers;
     private final WeakHashMap<Integer, WeakReference<EnumValueDescriptor>> unknownValues =
         new WeakHashMap<>();
 
@@ -1832,6 +1907,19 @@
       for (int i = 0; i < proto.getValueCount(); i++) {
         values[i] = new EnumValueDescriptor(proto.getValue(i), file, this, i);
       }
+      valuesSortedByNumber = values.clone();
+      Arrays.sort(valuesSortedByNumber, EnumValueDescriptor.BY_NUMBER);
+      // deduplicate
+      int j = 0;
+      for (int i = 1; i < proto.getValueCount(); i++) {
+        EnumValueDescriptor oldValue = valuesSortedByNumber[j];
+        EnumValueDescriptor newValue = valuesSortedByNumber[i];
+        if (oldValue.getNumber() != newValue.getNumber()) {
+          valuesSortedByNumber[++j] = newValue;
+        }
+      }
+      this.distinctNumbers = j + 1;
+      Arrays.fill(valuesSortedByNumber, distinctNumbers, proto.getValueCount(), null);
 
       file.pool.addSymbol(this);
     }
@@ -1855,6 +1943,22 @@
    */
   public static final class EnumValueDescriptor extends GenericDescriptor
       implements Internal.EnumLite {
+    static final Comparator<EnumValueDescriptor> BY_NUMBER =
+        new Comparator<EnumValueDescriptor>() {
+          @Override
+          public int compare(EnumValueDescriptor o1, EnumValueDescriptor o2) {
+            return Integer.compare(o1.getNumber(), o2.getNumber());
+          }
+        };
+
+    static final NumberGetter<EnumValueDescriptor> NUMBER_GETTER =
+        new NumberGetter<EnumValueDescriptor>() {
+          @Override
+          public int getNumber(EnumValueDescriptor enumValueDescriptor) {
+            return enumValueDescriptor.getNumber();
+          }
+        };
+
     /**
      * Get the index of this descriptor within its parent.
      *
@@ -1900,7 +2004,7 @@
     /** Get the {@link FileDescriptor} containing this descriptor. */
     @Override
     public FileDescriptor getFile() {
-      return file;
+      return type.file;
     }
 
     /** Get the value's enum type. */
@@ -1916,7 +2020,6 @@
     private final int index;
     private EnumValueDescriptorProto proto;
     private final String fullName;
-    private final FileDescriptor file;
     private final EnumDescriptor type;
 
     private EnumValueDescriptor(
@@ -1927,24 +2030,20 @@
         throws DescriptorValidationException {
       this.index = index;
       this.proto = proto;
-      this.file = file;
       type = parent;
 
       fullName = parent.getFullName() + '.' + proto.getName();
 
       file.pool.addSymbol(this);
-      file.pool.addEnumValueByNumber(this);
     }
 
     // Create an unknown enum value.
-    private EnumValueDescriptor(
-        final FileDescriptor file, final EnumDescriptor parent, final Integer number) {
+    private EnumValueDescriptor(final EnumDescriptor parent, final Integer number) {
       String name = "UNKNOWN_ENUM_VALUE_" + parent.getName() + "_" + number;
       EnumValueDescriptorProto proto =
           EnumValueDescriptorProto.newBuilder().setName(name).setNumber(number).build();
       this.index = -1;
       this.proto = proto;
-      this.file = file;
       this.type = parent;
       this.fullName = parent.getFullName() + '.' + proto.getName();
 
@@ -2156,8 +2255,9 @@
 
     private void crossLink() throws DescriptorValidationException {
       final GenericDescriptor input =
-          file.pool.lookupSymbol(
-              proto.getInputType(), this, DescriptorPool.SearchFilter.TYPES_ONLY);
+          getFile()
+              .pool
+              .lookupSymbol(proto.getInputType(), this, DescriptorPool.SearchFilter.TYPES_ONLY);
       if (!(input instanceof Descriptor)) {
         throw new DescriptorValidationException(
             this, '\"' + proto.getInputType() + "\" is not a message type.");
@@ -2165,8 +2265,9 @@
       inputType = (Descriptor) input;
 
       final GenericDescriptor output =
-          file.pool.lookupSymbol(
-              proto.getOutputType(), this, DescriptorPool.SearchFilter.TYPES_ONLY);
+          getFile()
+              .pool
+              .lookupSymbol(proto.getOutputType(), this, DescriptorPool.SearchFilter.TYPES_ONLY);
       if (!(output instanceof Descriptor)) {
         throw new DescriptorValidationException(
             this, '\"' + proto.getOutputType() + "\" is not a message type.");
@@ -2288,7 +2389,9 @@
     }
 
     DescriptorPool(final FileDescriptor[] dependencies, boolean allowUnknownDependencies) {
-      this.dependencies = new HashSet<>();
+      this.dependencies =
+          Collections.newSetFromMap(
+              new IdentityHashMap<FileDescriptor, Boolean>(dependencies.length));
       this.allowUnknownDependencies = allowUnknownDependencies;
 
       for (Descriptors.FileDescriptor dependency : dependencies) {
@@ -2321,8 +2424,6 @@
     private boolean allowUnknownDependencies;
 
     private final Map<String, GenericDescriptor> descriptorsByName = new HashMap<>();
-    private final Map<DescriptorIntPair, FieldDescriptor> fieldsByNumber = new HashMap<>();
-    private final Map<DescriptorIntPair, EnumValueDescriptor> enumValuesByNumber = new HashMap<>();
 
     /** Find a generic descriptor by fully-qualified name. */
     GenericDescriptor findSymbol(final String fullName) {
@@ -2581,68 +2682,6 @@
       }
     }
 
-    /** A (GenericDescriptor, int) pair, used as a map key. */
-    private static final class DescriptorIntPair {
-      private final GenericDescriptor descriptor;
-      private final int number;
-
-      DescriptorIntPair(final GenericDescriptor descriptor, final int number) {
-        this.descriptor = descriptor;
-        this.number = number;
-      }
-
-      @Override
-      public int hashCode() {
-        return descriptor.hashCode() * ((1 << 16) - 1) + number;
-      }
-
-      @Override
-      public boolean equals(final Object obj) {
-        if (!(obj instanceof DescriptorIntPair)) {
-          return false;
-        }
-        final DescriptorIntPair other = (DescriptorIntPair) obj;
-        return descriptor == other.descriptor && number == other.number;
-      }
-    }
-
-    /**
-     * Adds a field to the fieldsByNumber table. Throws an exception if a field with the same
-     * containing type and number already exists.
-     */
-    void addFieldByNumber(final FieldDescriptor field) throws DescriptorValidationException {
-      final DescriptorIntPair key =
-          new DescriptorIntPair(field.getContainingType(), field.getNumber());
-      final FieldDescriptor old = fieldsByNumber.put(key, field);
-      if (old != null) {
-        fieldsByNumber.put(key, old);
-        throw new DescriptorValidationException(
-            field,
-            "Field number "
-                + field.getNumber()
-                + " has already been used in \""
-                + field.getContainingType().getFullName()
-                + "\" by field \""
-                + old.getName()
-                + "\".");
-      }
-    }
-
-    /**
-     * Adds an enum value to the enumValuesByNumber table. If an enum value with the same type and
-     * number already exists, does nothing. (This is allowed; the first value define with the number
-     * takes precedence.)
-     */
-    void addEnumValueByNumber(final EnumValueDescriptor value) {
-      final DescriptorIntPair key = new DescriptorIntPair(value.getType(), value.getNumber());
-      final EnumValueDescriptor old = enumValuesByNumber.put(key, value);
-      if (old != null) {
-        enumValuesByNumber.put(key, old);
-        // Not an error:  Multiple enum values may have the same number, but
-        // we only want the first one in the map.
-      }
-    }
-
     /**
      * Verifies that the descriptor's name is valid (i.e. it contains only letters, digits, and
      * underscores, and does not start with a digit).
@@ -2660,9 +2699,10 @@
       // Subsequent characters may be letters, numbers, or digits.
       for (int i = 0; i < name.length(); i++) {
         final char c = name.charAt(i);
-        if (('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z')
-          || (c == '_')
-          || ('0' <= c && c <= '9' && i > 0)) {
+        if (('a' <= c && c <= 'z')
+            || ('A' <= c && c <= 'Z')
+            || (c == '_')
+            || ('0' <= c && c <= '9' && i > 0)) {
           // Valid
           continue;
         }
@@ -2752,4 +2792,27 @@
     private int fieldCount;
     private FieldDescriptor[] fields;
   }
+
+  private static <T> T binarySearch(T[] array, int size, NumberGetter<T> getter, int number) {
+    int left = 0;
+    int right = size - 1;
+
+    while (left <= right) {
+      int mid = (left + right) / 2;
+      T midValue = array[mid];
+      int midValueNumber = getter.getNumber(midValue);
+      if (number < midValueNumber) {
+        right = mid - 1;
+      } else if (number > midValueNumber) {
+        left = mid + 1;
+      } else {
+        return midValue;
+      }
+    }
+    return null;
+  }
+
+  private interface NumberGetter<T> {
+    int getNumber(T t);
+  }
 }
diff --git a/java/core/src/main/java/com/google/protobuf/Utf8.java b/java/core/src/main/java/com/google/protobuf/Utf8.java
index 104ab09..7d56ddd 100644
--- a/java/core/src/main/java/com/google/protobuf/Utf8.java
+++ b/java/core/src/main/java/com/google/protobuf/Utf8.java
@@ -1676,9 +1676,9 @@
       }
 
       // Read bytes until 8-byte aligned so that we can read longs in the loop below.
-      // We do this by ANDing the address with 7 to determine the number of bytes that need to
-      // be read before we're 8-byte aligned.
-      final int unaligned = 8 - ((int) address & 7);
+      // This is equivalent to (8-address) mod 8, the number of bytes we need to read before we're
+      // 8-byte aligned.
+      final int unaligned = (int) (-address & 7);
       for (int j = unaligned; j > 0; j--) {
         if (UnsafeUtil.getByte(address++) < 0) {
           return unaligned - j;
diff --git a/java/core/src/test/java/com/google/protobuf/GeneratedMessageTest.java b/java/core/src/test/java/com/google/protobuf/GeneratedMessageTest.java
index fbba612..e504766 100644
--- a/java/core/src/test/java/com/google/protobuf/GeneratedMessageTest.java
+++ b/java/core/src/test/java/com/google/protobuf/GeneratedMessageTest.java
@@ -65,6 +65,8 @@
 import protobuf_unittest.UnittestProto.TestUnpackedTypes;
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
 import java.io.ObjectInputStream;
 import java.io.ObjectOutputStream;
 import java.util.Arrays;
@@ -1748,6 +1750,41 @@
   }
 
   @Test
+  public void testOneofParseFailurePropagatesUnderlyingException() {
+    final byte[] bytes = TestOneof2.newBuilder().setFooInt(123).build().toByteArray();
+    final IOException injectedException = new IOException("oh no");
+    CodedInputStream failingInputStream =
+        CodedInputStream.newInstance(
+            new InputStream() {
+              boolean first = true;
+
+              @Override
+              public int read(byte[] b, int off, int len) throws IOException {
+                if (!first) {
+                  throw injectedException;
+                }
+                first = false;
+                System.arraycopy(bytes, 0, b, off, len);
+                return len;
+              }
+
+              @Override
+              public int read() {
+                throw new UnsupportedOperationException();
+              }
+            },
+            bytes.length - 1);
+    TestOneof2.Builder builder = TestOneof2.newBuilder();
+
+    try {
+      builder.mergeFrom(failingInputStream, ExtensionRegistry.getEmptyRegistry());
+      assertWithMessage("Expected mergeFrom to fail").fail();
+    } catch (IOException e) {
+      assertThat(e).isSameInstanceAs(injectedException);
+    }
+  }
+
+  @Test
   public void testGetRepeatedFieldBuilder() {
     Descriptor descriptor = TestAllTypes.getDescriptor();
 
diff --git a/java/core/src/test/java/com/google/protobuf/MapForProto2LiteTest.java b/java/core/src/test/java/com/google/protobuf/MapForProto2LiteTest.java
index ed07739..1a767c0 100644
--- a/java/core/src/test/java/com/google/protobuf/MapForProto2LiteTest.java
+++ b/java/core/src/test/java/com/google/protobuf/MapForProto2LiteTest.java
@@ -43,8 +43,8 @@
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.HashMap;
+import java.util.LinkedHashMap;
 import java.util.Map;
-import java.util.TreeMap;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.junit.runners.JUnit4;
@@ -335,8 +335,19 @@
     assertMapValuesSet(destination.build());
   }
 
+    @Test
+  public void testPutChecksNullKey() throws Exception {
+    TestMap.Builder builder = TestMap.newBuilder();
+
+    try {
+      builder.putStringToInt32Field(null, 1);
+      assertWithMessage("expected exception").fail();
+    } catch (NullPointerException expected) {
+    }
+  }
+
   @Test
-  public void testPutChecksNullKeysAndValues() throws Exception {
+  public void testPutChecksNullValues() throws Exception {
     TestMap.Builder builder = TestMap.newBuilder();
 
     try {
@@ -807,11 +818,30 @@
   }
 
   @Test
+  public void testPutAllWithNullStringKey() throws Exception {
+    TestMap.Builder sourceBuilder = TestMap.newBuilder();
+
+    // order preserving map used here to help test rollback
+    Map<Integer, String> data = new LinkedHashMap<>();
+    data.put(7, "foo");
+    data.put(null, "bar");
+    data.put(9, "baz");
+    try {
+      sourceBuilder.putAllInt32ToStringField(data);
+      fail("allowed null string key");
+    } catch (NullPointerException expected) {
+      // Verify rollback of previously added values.
+      // They all go in or none do.
+      assertThat(sourceBuilder.getInt32ToStringFieldMap()).isEmpty();
+    }
+  }
+
+  @Test
   public void testPutAllWithNullStringValue() throws Exception {
     TestMap.Builder sourceBuilder = TestMap.newBuilder();
 
     // order preserving map used here to help test rollback
-    Map<Integer, String> data = new TreeMap<>();
+    Map<Integer, String> data = new LinkedHashMap<>();
     data.put(7, "foo");
     data.put(8, "bar");
     data.put(9, null);
diff --git a/java/core/src/test/java/com/google/protobuf/MapForProto2Test.java b/java/core/src/test/java/com/google/protobuf/MapForProto2Test.java
index 1d6a0dd..6681724 100644
--- a/java/core/src/test/java/com/google/protobuf/MapForProto2Test.java
+++ b/java/core/src/test/java/com/google/protobuf/MapForProto2Test.java
@@ -51,6 +51,7 @@
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.HashMap;
+import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.TreeMap;
@@ -484,7 +485,7 @@
   }
 
   @Test
-  public void testPutChecksNullKeysAndValues() throws Exception {
+  public void testPutChecksNullValues() throws Exception {
     TestMap.Builder builder = TestMap.newBuilder();
 
     try {
@@ -517,6 +518,17 @@
   }
 
   @Test
+  public void testPutChecksNullKey() throws Exception {
+    TestMap.Builder builder = TestMap.newBuilder();
+
+    try {
+      builder.putStringToInt32Field(null, 1);
+      assertWithMessage("expected exception").fail();
+    } catch (NullPointerException expected) {
+    }
+  }
+
+  @Test
   public void testSerializeAndParse() throws Exception {
     TestMap.Builder builder = TestMap.newBuilder();
     setMapValuesUsingAccessors(builder);
@@ -1235,6 +1247,25 @@
   }
 
   @Test
+  public void testPutAllWithNullStringKey() throws Exception {
+    TestMap.Builder sourceBuilder = TestMap.newBuilder();
+
+    // order preserving map used here to help test rollback
+    Map<Integer, String> data = new LinkedHashMap<>();
+    data.put(7, "foo");
+    data.put(null, "bar");
+    data.put(9, "baz");
+    try {
+      sourceBuilder.putAllInt32ToStringField(data);
+      fail("allowed null string key");
+    } catch (NullPointerException expected) {
+      // Verify rollback of previously added values.
+      // They all go in or none do.
+      assertThat(sourceBuilder.getInt32ToStringFieldMap()).isEmpty();
+    }
+  }
+
+  @Test
   public void testPutNullStringValue() throws Exception {
     TestMap.Builder sourceBuilder = TestMap.newBuilder();
 
diff --git a/java/core/src/test/java/com/google/protobuf/Utf8Utils.java b/java/core/src/test/java/com/google/protobuf/Utf8Utils.java
index dbd3d39..6b03186 100644
--- a/java/core/src/test/java/com/google/protobuf/Utf8Utils.java
+++ b/java/core/src/test/java/com/google/protobuf/Utf8Utils.java
@@ -171,20 +171,19 @@
           codePoint = rnd.nextInt(distribution[3]);
           if (codePoint < distribution[0]) {
             // 1 bytes
-            sb.append(0x7F);
+            sb.append((char) 0x7F);
           } else if (codePoint < distribution[1]) {
             // 2 bytes
-            sb.append(0x7FF);
+            sb.append((char) 0x7FF);
           } else if (codePoint < distribution[2]) {
             // 3 bytes
-            sb.append(MIN_SURROGATE - 1);
+            sb.append((char) (MIN_SURROGATE - 1));
           } else {
             // 4 bytes
             sb.append(MIN_HIGH_SURROGATE);
             sb.append(MIN_LOW_SURROGATE);
           }
         } while (Utf8Utils.isSurrogate(codePoint));
-        sb.appendCodePoint(codePoint);
       }
       strings[i] = sb.toString();
     }
diff --git a/java/kotlin-lite/pom.xml b/java/kotlin-lite/pom.xml
index 8c4b1f8..d6342ee 100644
--- a/java/kotlin-lite/pom.xml
+++ b/java/kotlin-lite/pom.xml
@@ -4,7 +4,7 @@
   <parent>
     <groupId>com.google.protobuf</groupId>
     <artifactId>protobuf-parent</artifactId>
-    <version>3.17.3</version>
+    <version>3.18.0</version>
   </parent>
 
   <artifactId>protobuf-kotlin-lite</artifactId>
diff --git a/java/kotlin/pom.xml b/java/kotlin/pom.xml
index 756611c..263be68 100644
--- a/java/kotlin/pom.xml
+++ b/java/kotlin/pom.xml
@@ -4,7 +4,7 @@
   <parent>
     <groupId>com.google.protobuf</groupId>
     <artifactId>protobuf-parent</artifactId>
-    <version>3.17.3</version>
+    <version>3.18.0</version>
   </parent>
 
   <artifactId>protobuf-kotlin</artifactId>
diff --git a/java/lite/pom.xml b/java/lite/pom.xml
index 1c09a3c..358ba46 100644
--- a/java/lite/pom.xml
+++ b/java/lite/pom.xml
@@ -4,7 +4,7 @@
   <parent>
     <groupId>com.google.protobuf</groupId>
     <artifactId>protobuf-parent</artifactId>
-    <version>3.17.3</version>
+    <version>3.18.0</version>
   </parent>
 
   <artifactId>protobuf-javalite</artifactId>
@@ -104,6 +104,8 @@
                     <include>ByteBufferWriter.java</include>
                     <include>ByteOutput.java</include>
                     <include>ByteString.java</include>
+                    <include>CanIgnoreReturnValue.java</include>
+                    <include>CheckReturnValue.java</include>
                     <include>CodedInputStream.java</include>
                     <include>CodedInputStreamReader.java</include>
                     <include>CodedOutputStream.java</include>
diff --git a/java/lite/src/test/java/com/google/protobuf/LiteTest.java b/java/lite/src/test/java/com/google/protobuf/LiteTest.java
index 7cbc764..3680cc2 100644
--- a/java/lite/src/test/java/com/google/protobuf/LiteTest.java
+++ b/java/lite/src/test/java/com/google/protobuf/LiteTest.java
@@ -55,6 +55,7 @@
 import map_lite_test.MapTestProto.TestMap.MessageValue;
 import protobuf_unittest.NestedExtensionLite;
 import protobuf_unittest.NonNestedExtensionLite;
+import protobuf_unittest.UnittestProto.TestOneof2;
 import protobuf_unittest.lite_equals_and_hash.LiteEqualsAndHash.Bar;
 import protobuf_unittest.lite_equals_and_hash.LiteEqualsAndHash.BarPrime;
 import protobuf_unittest.lite_equals_and_hash.LiteEqualsAndHash.Foo;
@@ -1430,6 +1431,41 @@
   }
 
   @Test
+  public void testMergeFrom_failureWhenReadingValue_propagatesOriginalException() {
+    final byte[] bytes = TestOneof2.newBuilder().setFooInt(123).build().toByteArray();
+    final IOException injectedException = new IOException("oh no");
+    CodedInputStream failingInputStream =
+        CodedInputStream.newInstance(
+            new InputStream() {
+              boolean first = true;
+
+              @Override
+              public int read(byte[] b, int off, int len) throws IOException {
+                if (!first) {
+                  throw injectedException;
+                }
+                first = false;
+                System.arraycopy(bytes, 0, b, off, len);
+                return len;
+              }
+
+              @Override
+              public int read() {
+                throw new UnsupportedOperationException();
+              }
+            },
+            bytes.length - 1);
+    TestOneof2.Builder builder = TestOneof2.newBuilder();
+
+    try {
+      builder.mergeFrom(failingInputStream, ExtensionRegistryLite.getEmptyRegistry());
+      assertWithMessage("Expected mergeFrom to fail").fail();
+    } catch (IOException e) {
+      assertThat(e).isSameInstanceAs(injectedException);
+    }
+  }
+
+  @Test
   public void testToStringDefaultInstance() throws Exception {
     assertToStringEquals("", TestAllTypesLite.getDefaultInstance());
   }
diff --git a/java/pom.xml b/java/pom.xml
index d85e430..d8a4b97 100644
--- a/java/pom.xml
+++ b/java/pom.xml
@@ -4,7 +4,7 @@
 
   <groupId>com.google.protobuf</groupId>
   <artifactId>protobuf-parent</artifactId>
-  <version>3.17.3</version>
+  <version>3.18.0</version>
   <packaging>pom</packaging>
 
   <name>Protocol Buffers [Parent]</name>
diff --git a/java/util/pom.xml b/java/util/pom.xml
index 63f82c8..8a8e159 100644
--- a/java/util/pom.xml
+++ b/java/util/pom.xml
@@ -4,7 +4,7 @@
   <parent>
     <groupId>com.google.protobuf</groupId>
     <artifactId>protobuf-parent</artifactId>
-    <version>3.17.3</version>
+    <version>3.18.0</version>
   </parent>
 
   <artifactId>protobuf-java-util</artifactId>
diff --git a/java/util/src/main/java/com/google/protobuf/util/JsonFormat.java b/java/util/src/main/java/com/google/protobuf/util/JsonFormat.java
index 2383da6..d94fb3d 100644
--- a/java/util/src/main/java/com/google/protobuf/util/JsonFormat.java
+++ b/java/util/src/main/java/com/google/protobuf/util/JsonFormat.java
@@ -1558,7 +1558,7 @@
       try {
         Timestamp value = Timestamps.parse(json.getAsString());
         builder.mergeFrom(value.toByteString());
-      } catch (ParseException e) {
+      } catch (ParseException | UnsupportedOperationException e) {
         throw new InvalidProtocolBufferException("Failed to parse timestamp: " + json);
       }
     }
@@ -1568,7 +1568,7 @@
       try {
         Duration value = Durations.parse(json.getAsString());
         builder.mergeFrom(value.toByteString());
-      } catch (ParseException e) {
+      } catch (ParseException | UnsupportedOperationException e) {
         throw new InvalidProtocolBufferException("Failed to parse duration: " + json);
       }
     }
diff --git a/java/util/src/main/java/com/google/protobuf/util/Timestamps.java b/java/util/src/main/java/com/google/protobuf/util/Timestamps.java
index 8461f67..c9276a0 100644
--- a/java/util/src/main/java/com/google/protobuf/util/Timestamps.java
+++ b/java/util/src/main/java/com/google/protobuf/util/Timestamps.java
@@ -38,6 +38,7 @@
 
 import com.google.errorprone.annotations.CanIgnoreReturnValue;
 import com.google.errorprone.annotations.CompileTimeConstant;
+import com.google.j2objc.annotations.J2ObjCIncompatible;
 import com.google.protobuf.Duration;
 import com.google.protobuf.Timestamp;
 import java.io.Serializable;
@@ -329,6 +330,27 @@
   }
 
   /**
+   * Create a Timestamp from a java.util.Date. If the java.util.Date is a java.sql.Timestamp,
+   * full nanonsecond precision is retained.
+   *
+   * @throws IllegalArgumentException if the year is before 1 CE or after 9999 CE
+   */
+  @SuppressWarnings("GoodTime") // this is a legacy conversion API
+  @J2ObjCIncompatible
+  public static Timestamp fromDate(Date date) {
+    if (date instanceof java.sql.Timestamp) {
+      java.sql.Timestamp sqlTimestamp = (java.sql.Timestamp) date;
+      long integralSeconds = sqlTimestamp.getTime() / 1000L; // truncate the fractional seconds
+      return Timestamp.newBuilder()
+          .setSeconds(integralSeconds)
+          .setNanos(sqlTimestamp.getNanos())
+          .build();
+    } else {
+      return fromMillis(date.getTime());
+    }
+  }
+
+  /**
    * Convert a Timestamp to the number of milliseconds elapsed from the epoch.
    *
    * <p>The result will be rounded down to the nearest millisecond. E.g., if the timestamp
diff --git a/java/util/src/test/java/com/google/protobuf/util/JsonFormatTest.java b/java/util/src/test/java/com/google/protobuf/util/JsonFormatTest.java
index fc61a28..bd58cc9 100644
--- a/java/util/src/test/java/com/google/protobuf/util/JsonFormatTest.java
+++ b/java/util/src/test/java/com/google/protobuf/util/JsonFormatTest.java
@@ -822,6 +822,21 @@
   }
 
   @Test
+  public void testTimestampMergeError() throws Exception {
+    final String incorrectTimestampString = "{\"seconds\":1800,\"nanos\":0}";
+    try {
+      TestTimestamp.Builder builder = TestTimestamp.newBuilder();
+      mergeFromJson(String.format("{\"timestamp_value\": %s}", incorrectTimestampString), builder);
+      assertWithMessage("expected exception").fail();
+    } catch (InvalidProtocolBufferException e) {
+      // Exception expected.
+      assertThat(e)
+          .hasMessageThat()
+          .isEqualTo("Failed to parse timestamp: " + incorrectTimestampString);
+    }
+  }
+
+  @Test
   public void testDuration() throws Exception {
     TestDuration message =
         TestDuration.newBuilder().setDurationValue(Durations.parse("12345s")).build();
@@ -831,6 +846,21 @@
   }
 
   @Test
+  public void testDurationMergeError() throws Exception {
+    final String incorrectDurationString = "{\"seconds\":10,\"nanos\":500}";
+    try {
+      TestDuration.Builder builder = TestDuration.newBuilder();
+      mergeFromJson(String.format("{\"duration_value\": %s}", incorrectDurationString), builder);
+      assertWithMessage("expected exception").fail();
+    } catch (InvalidProtocolBufferException e) {
+      // Exception expected.
+      assertThat(e)
+          .hasMessageThat()
+          .isEqualTo("Failed to parse duration: " + incorrectDurationString);
+    }
+  }
+
+  @Test
   public void testFieldMask() throws Exception {
     TestFieldMask message =
         TestFieldMask.newBuilder()
diff --git a/js/binary/utils.js b/js/binary/utils.js
index 4d74331..d281027 100644
--- a/js/binary/utils.js
+++ b/js/binary/utils.js
@@ -202,7 +202,11 @@
 
   exp = Math.floor(Math.log(value) / Math.LN2);
   mant = value * Math.pow(2, -exp);
-  mant = Math.round(mant * jspb.BinaryConstants.TWO_TO_23) & 0x7FFFFF;
+  mant = Math.round(mant * jspb.BinaryConstants.TWO_TO_23);
+  if (mant >= 0x1000000) {
+    ++exp;
+  }
+  mant = mant & 0x7FFFFF;
 
   jspb.utils.split64High = 0;
   jspb.utils.split64Low = ((sign << 31) | ((exp + 127) << 23) | mant) >>> 0;
diff --git a/js/binary/utils_test.js b/js/binary/utils_test.js
index 9f735d3..bc1707d 100644
--- a/js/binary/utils_test.js
+++ b/js/binary/utils_test.js
@@ -391,6 +391,11 @@
     // Pi.
     test(f32_pi, 0x40490fdb);
 
+    // corner cases
+    test(0.9999999762949594, 0x3f800000);
+    test(7.99999999999999, 0x41000000);
+    test(Math.sin(30 * Math.PI / 180), 0x3f000000); // sin(30 degrees)
+
     // Various positive values.
     var cursor = f32_eps * 10;
     while (cursor != Infinity) {
diff --git a/js/package.json b/js/package.json
index 8121aac..10426a3 100644
--- a/js/package.json
+++ b/js/package.json
@@ -1,6 +1,6 @@
 {
   "name": "google-protobuf",
-  "version": "3.17.3",
+  "version": "3.18.0",
   "description": "Protocol Buffers for JavaScript",
   "main": "google-protobuf.js",
   "files": [
diff --git a/kokoro/linux/dockerfile/test/java_stretch/Dockerfile b/kokoro/linux/dockerfile/test/java_stretch/Dockerfile
index 3e72046..b9f562a 100644
--- a/kokoro/linux/dockerfile/test/java_stretch/Dockerfile
+++ b/kokoro/linux/dockerfile/test/java_stretch/Dockerfile
@@ -24,7 +24,7 @@
   maven \
   openjdk-8-jdk \
   # Python dependencies
-  python-setuptools \
-  python-pip \
+  python3-setuptools \
+  python3-pip \
   virtualenv \
   && apt-get clean
diff --git a/kokoro/linux/php_all/build.sh b/kokoro/linux/php_all/build.sh
index 1ee79ad..cfcab00 100755
--- a/kokoro/linux/php_all/build.sh
+++ b/kokoro/linux/php_all/build.sh
@@ -15,6 +15,9 @@
 docker run $(test -t 0 && echo "-it") -v$PWD:/workspace gcr.io/protobuf-build/php/linux:7.4.18-dbg-14a06550010c0649bf69b6c9b803c1ca609bbb6d "composer test && composer test_c"
 docker run $(test -t 0 && echo "-it") -v$PWD:/workspace gcr.io/protobuf-build/php/linux:8.0.5-dbg-14a06550010c0649bf69b6c9b803c1ca609bbb6d "composer test && composer test_c"
 
+# Run specialized memory leak & multirequest tests.
+docker run $(test -t 0 && echo "-it") -v$PWD:/workspace gcr.io/protobuf-build/php/linux:8.0.5-dbg-14a06550010c0649bf69b6c9b803c1ca609bbb6d "composer test_c && tests/multirequest.sh && tests/memory_leak_test.sh"
+
 # Most of our tests use a debug build of PHP, but we do one build against an opt
 # php just in case that surfaces anything unexpected.
 docker run $(test -t 0 && echo "-it") -v$PWD:/workspace gcr.io/protobuf-build/php/linux:8.0.5-14a06550010c0649bf69b6c9b803c1ca609bbb6d "composer test && composer test_c"
diff --git a/kokoro/macos/objectivec_cocoapods_integration/build.sh b/kokoro/macos/objectivec_cocoapods_integration/build.sh
index 8f3c9b4..f96d289 100755
--- a/kokoro/macos/objectivec_cocoapods_integration/build.sh
+++ b/kokoro/macos/objectivec_cocoapods_integration/build.sh
@@ -6,7 +6,6 @@
 cd $(dirname $0)/../../..
 
 # Prepare worker environment to run tests
-KOKORO_INSTALL_COCOAPODS=yes
 source kokoro/macos/prepare_build_macos_rc
 
 ./tests.sh objectivec_cocoapods_integration
diff --git a/kokoro/macos/prepare_build_macos_rc b/kokoro/macos/prepare_build_macos_rc
index dcd17f3..ef428fc 100755
--- a/kokoro/macos/prepare_build_macos_rc
+++ b/kokoro/macos/prepare_build_macos_rc
@@ -20,58 +20,6 @@
 export CXX=g++
 
 ##
-# Brew: update, then upgrade the installed tools to current version and install
-# some needed ones not in the Kokoro base image. This ensure current versions
-# of CMake, autotools, etc.
-
-# But first...
-#
-# The transitive deps of the installed tools need protobuf, but Kokoro manually
-# installed it outside of brew so it needs to be removed so brew can install the
-# tools (and a newer version of protobuf). g/kokoro-users/7FRvQMUdN40 about why
-# it is a manual install vs. a brew install in the first place.
-sudo rm -rf \
-    /usr/local/include/google/protobuf \
-    /usr/local/bin/protoc
-# Likewise, updating python can have issues because of some existing binaries.
-sudo rm -rf \
-    /usr/local/bin/2to3* \
-    /usr/local/bin/idle3* \
-    /usr/local/bin/pip3 \
-    /usr/local/bin/pydoc3* \
-    /usr/local/bin/python3* \
-    /usr/local/bin/pyvenv*
-
-git -C /usr/local/Homebrew/Library/Taps/homebrew/homebrew-core fetch --unshallow
-git -C /usr/local/Homebrew/Library/Taps/homebrew/homebrew-cask fetch --unshallow
-
-# This is needed to fix a conflict between the ilmbase and imath packages,
-# which seem to conflict with each other by both trying to install
-# libImath.dylib.
-brew unlink ilmbase
-
-brew update
-brew upgrade
-
-##
-# Install Ruby
-
-if [[ "${KOKORO_INSTALL_RUBY:-}" == "yes" ]] ; then
-  brew install ruby
-fi
-
-##
-# Install Cocoapods
-
-if [[ "${KOKORO_INSTALL_COCOAPODS:-}" == "yes" ]] ; then
-  # The existing cocoapods was installed via gem, but that doesn't work well
-  # with the overlap in deps with things managed by brew (errors around ruby
-  # versions, etc.); so remove it and install in via brew instead.
-  gem uninstall -a "$(gem list | grep cocoapods | cut -d ' ' -f 1)"
-  brew install cocoapods
-fi
-
-##
 # Install Tox
 
 if [[ "${KOKORO_INSTALL_TOX:-}" == "yes" ]] ; then
@@ -85,5 +33,5 @@
   curl -sSL https://rvm.io/mpapis.asc | gpg --import -
   curl -sSL https://rvm.io/pkuczynski.asc | gpg --import -
 
-  curl -sSL https://get.rvm.io | bash -s master --ruby
+  curl -sSL https://get.rvm.io | bash -s stable --ruby
 fi
diff --git a/kokoro/macos/ruby23/build.sh b/kokoro/macos/ruby23/build.sh
index 9317838..5a29a99 100755
--- a/kokoro/macos/ruby23/build.sh
+++ b/kokoro/macos/ruby23/build.sh
@@ -6,7 +6,6 @@
 cd $(dirname $0)/../../..
 
 # Prepare worker environment to run tests
-KOKORO_INSTALL_RUBY=yes
 KOKORO_INSTALL_RVM=yes
 source kokoro/macos/prepare_build_macos_rc
 
diff --git a/kokoro/macos/ruby24/build.sh b/kokoro/macos/ruby24/build.sh
index 51bb2e6..10ac85f 100755
--- a/kokoro/macos/ruby24/build.sh
+++ b/kokoro/macos/ruby24/build.sh
@@ -6,7 +6,6 @@
 cd $(dirname $0)/../../..
 
 # Prepare worker environment to run tests
-KOKORO_INSTALL_RUBY=yes
 KOKORO_INSTALL_RVM=yes
 source kokoro/macos/prepare_build_macos_rc
 
diff --git a/kokoro/macos/ruby25/build.sh b/kokoro/macos/ruby25/build.sh
index ba2d0a4..48c8940 100755
--- a/kokoro/macos/ruby25/build.sh
+++ b/kokoro/macos/ruby25/build.sh
@@ -6,7 +6,6 @@
 cd $(dirname $0)/../../..
 
 # Prepare worker environment to run tests
-KOKORO_INSTALL_RUBY=yes
 KOKORO_INSTALL_RVM=yes
 source kokoro/macos/prepare_build_macos_rc
 
diff --git a/kokoro/macos/ruby26/build.sh b/kokoro/macos/ruby26/build.sh
index 5a4c243..1b94fe1 100755
--- a/kokoro/macos/ruby26/build.sh
+++ b/kokoro/macos/ruby26/build.sh
@@ -6,7 +6,6 @@
 cd $(dirname $0)/../../..
 
 # Prepare worker environment to run tests
-KOKORO_INSTALL_RUBY=yes
 KOKORO_INSTALL_RVM=yes
 source kokoro/macos/prepare_build_macos_rc
 
diff --git a/kokoro/macos/ruby27/build.sh b/kokoro/macos/ruby27/build.sh
index b1529b9..baebdb7 100755
--- a/kokoro/macos/ruby27/build.sh
+++ b/kokoro/macos/ruby27/build.sh
@@ -6,7 +6,6 @@
 cd $(dirname $0)/../../..
 
 # Prepare worker environment to run tests
-KOKORO_INSTALL_RUBY=yes
 KOKORO_INSTALL_RVM=yes
 source kokoro/macos/prepare_build_macos_rc
 
diff --git a/kokoro/macos/ruby30/build.sh b/kokoro/macos/ruby30/build.sh
index 6b9bfb3..b1e0641 100755
--- a/kokoro/macos/ruby30/build.sh
+++ b/kokoro/macos/ruby30/build.sh
@@ -6,7 +6,6 @@
 cd $(dirname $0)/../../..
 
 # Prepare worker environment to run tests
-KOKORO_INSTALL_RUBY=yes
 KOKORO_INSTALL_RVM=yes
 source kokoro/macos/prepare_build_macos_rc
 
diff --git a/kokoro/release/python/linux/build_artifacts.sh b/kokoro/release/python/linux/build_artifacts.sh
index 4205975..2407a30 100755
--- a/kokoro/release/python/linux/build_artifacts.sh
+++ b/kokoro/release/python/linux/build_artifacts.sh
@@ -37,8 +37,6 @@
   before_install
 
   clean_code $REPO_DIR $BUILD_COMMIT
-  sed -i '/Wno-sign-compare/a \ \ \ \ \ \ \ \ extra_compile_args.append("-std=c++11")' $REPO_DIR/python/setup.py
-  cat $REPO_DIR/python/setup.py
 
   build_wheel $REPO_DIR/python $PLAT
 
diff --git a/objectivec/DevTools/check_version_stamps.sh b/objectivec/DevTools/check_version_stamps.sh
index 1acbe2a..a3524cb 100755
--- a/objectivec/DevTools/check_version_stamps.sh
+++ b/objectivec/DevTools/check_version_stamps.sh
@@ -25,7 +25,7 @@
   # Collect version from generator sources.
   local GeneratorVersion=$( \
       cat "${GeneratorSrc}" \
-          | sed -n -e "s:const int32 ${ConstantName} = \([0-9]*\);:\1:p"
+          | sed -n -e "s:const int32_t ${ConstantName} = \([0-9]*\);:\1:p"
   )
   if [[ -z "${GeneratorVersion}" ]] ; then
       die "Failed to find ${ConstantName} in the generator source (${GeneratorSrc})."
diff --git a/objectivec/DevTools/full_mac_build.sh b/objectivec/DevTools/full_mac_build.sh
index 9319b55..49b0ff4 100755
--- a/objectivec/DevTools/full_mac_build.sh
+++ b/objectivec/DevTools/full_mac_build.sh
@@ -289,7 +289,7 @@
           -disable-concurrent-destination-testing
       )
       ;;
-    11.* | 12.*)
+    11.* | 12.* | 13.*)
       # Dropped 32bit as Apple doesn't seem support the simulators either.
       XCODEBUILD_TEST_BASE_IOS+=(
           -destination "platform=iOS Simulator,name=iPhone 8,OS=latest" # 64bit
@@ -357,6 +357,11 @@
         -destination "platform=tvOS Simulator,name=Apple TV 4K,OS=latest"
       )
       ;;
+    13.*)
+      XCODEBUILD_TEST_BASE_TVOS+=(
+        -destination "platform=tvOS Simulator,name=Apple TV 4K (2nd generation),OS=latest"
+      )
+      ;;
     * )
       echo ""
       echo "ATTENTION: Time to update the simulator targets for Xcode ${XCODE_VERSION}"
diff --git a/php/ext/google/protobuf/array.c b/php/ext/google/protobuf/array.c
index 765e902..2c9a710 100644
--- a/php/ext/google/protobuf/array.c
+++ b/php/ext/google/protobuf/array.c
@@ -640,8 +640,8 @@
                    repeated_field_methods);
 
   RepeatedField_class_entry = zend_register_internal_class(&tmp_ce);
-  zend_class_implements(RepeatedField_class_entry, 3, spl_ce_ArrayAccess,
-                        zend_ce_aggregate, spl_ce_Countable);
+  zend_class_implements(RepeatedField_class_entry, 3, zend_ce_arrayaccess,
+                        zend_ce_aggregate, zend_ce_countable);
   RepeatedField_class_entry->ce_flags |= ZEND_ACC_FINAL;
   RepeatedField_class_entry->create_object = RepeatedField_create;
 
diff --git a/php/ext/google/protobuf/def.c b/php/ext/google/protobuf/def.c
index 88c201f..6662383 100644
--- a/php/ext/google/protobuf/def.c
+++ b/php/ext/google/protobuf/def.c
@@ -731,44 +731,25 @@
 }
 
 /**
- * Object handler to create an DescriptorPool.
- */
-static zend_object* DescriptorPool_create(zend_class_entry *class_type) {
-  DescriptorPool *intern = emalloc(sizeof(DescriptorPool));
-  zend_object_std_init(&intern->std, class_type);
-  intern->std.handlers = &DescriptorPool_object_handlers;
-  intern->symtab = upb_symtab_new();
-  // Skip object_properties_init(), we don't allow derived classes.
-  return &intern->std;
-}
-
-/**
  * Object handler to free an DescriptorPool.
  */
 static void DescriptorPool_destructor(zend_object* obj) {
   DescriptorPool* intern = (DescriptorPool*)obj;
-  if (intern->symtab) {
-    upb_symtab_free(intern->symtab);
-  }
-  intern->symtab = NULL;
+
+  // We can't free our underlying symtab here, because user code may create
+  // messages from destructors that will refer to it. The symtab will be freed
+  // by our RSHUTDOWN() handler in protobuf.c
+
   zend_object_std_dtor(&intern->std);
 }
 
 void DescriptorPool_CreateWithSymbolTable(zval *zv, upb_symtab *symtab) {
-  ZVAL_OBJ(zv, DescriptorPool_create(DescriptorPool_class_entry));
+  DescriptorPool *intern = emalloc(sizeof(DescriptorPool));
+  zend_object_std_init(&intern->std, DescriptorPool_class_entry);
+  intern->std.handlers = &DescriptorPool_object_handlers;
+  intern->symtab = symtab;
 
-  if (symtab) {
-    DescriptorPool *intern = GetPool(zv);
-    upb_symtab_free(intern->symtab);
-    intern->symtab = symtab;
-  }
-}
-
-upb_symtab *DescriptorPool_Steal(zval *zv) {
-  DescriptorPool *intern = GetPool(zv);
-  upb_symtab *ret = intern->symtab;
-  intern->symtab = NULL;
-  return ret;
+  ZVAL_OBJ(zv, &intern->std);
 }
 
 upb_symtab *DescriptorPool_GetSymbolTable() {
@@ -1120,7 +1101,7 @@
                    DescriptorPool_methods);
   DescriptorPool_class_entry = zend_register_internal_class(&tmp_ce);
   DescriptorPool_class_entry->ce_flags |= ZEND_ACC_FINAL;
-  DescriptorPool_class_entry->create_object = DescriptorPool_create;
+  DescriptorPool_class_entry->create_object = CreateHandler_ReturnNull;
   h = &DescriptorPool_object_handlers;
   memcpy(h, &std_object_handlers, sizeof(zend_object_handlers));
   h->dtor_obj = DescriptorPool_destructor;
diff --git a/php/ext/google/protobuf/def.h b/php/ext/google/protobuf/def.h
index e705642..ed944ab 100644
--- a/php/ext/google/protobuf/def.h
+++ b/php/ext/google/protobuf/def.h
@@ -38,15 +38,10 @@
 // Initializes the Def module, which defines all of the descriptor classes.
 void Def_ModuleInit();
 
-// Creates a new DescriptorPool to wrap the given symtab. The DescriptorPool
-// takes ownership of the given symtab. If symtab is NULL, the DescriptorPool
-// will create an empty symtab instead.
+// Creates a new DescriptorPool to wrap the given symtab, which must not be
+// NULL.
 void DescriptorPool_CreateWithSymbolTable(zval *zv, upb_symtab *symtab);
 
-// Given a zval representing a DescriptorPool, steals and returns its symtab,
-// which is now owned by the caller.
-upb_symtab *DescriptorPool_Steal(zval *zv);
-
 upb_symtab *DescriptorPool_GetSymbolTable();
 
 // Returns true if the global descriptor pool already has the given filename.
diff --git a/php/ext/google/protobuf/map.c b/php/ext/google/protobuf/map.c
index f5890d9..bbdfe29 100644
--- a/php/ext/google/protobuf/map.c
+++ b/php/ext/google/protobuf/map.c
@@ -636,8 +636,8 @@
                    MapField_methods);
 
   MapField_class_entry = zend_register_internal_class(&tmp_ce);
-  zend_class_implements(MapField_class_entry, 3, spl_ce_ArrayAccess,
-                        zend_ce_aggregate, spl_ce_Countable);
+  zend_class_implements(MapField_class_entry, 3, zend_ce_arrayaccess,
+                        zend_ce_aggregate, zend_ce_countable);
   MapField_class_entry->ce_flags |= ZEND_ACC_FINAL;
   MapField_class_entry->create_object = MapField_create;
 
diff --git a/php/ext/google/protobuf/package.xml b/php/ext/google/protobuf/package.xml
index 30f5048..7cf1a81 100644
--- a/php/ext/google/protobuf/package.xml
+++ b/php/ext/google/protobuf/package.xml
@@ -10,11 +10,11 @@
   <email>[email protected]</email>
   <active>yes</active>
  </lead>
- <date>2021-06-04</date>
- <time>21:17:28</time>
+ <date>2021-09-13</date>
+ <time>11:30:58</time>
  <version>
-  <release>3.17.3</release>
-  <api>3.17.3</api>
+  <release>3.18.0</release>
+  <api>3.18.0</api>
  </version>
  <stability>
   <release>stable</release>
@@ -22,7 +22,7 @@
  </stability>
  <license uri="https://opensource.org/licenses/BSD-3-Clause">3-Clause BSD License</license>
  <notes>
- * No new changes in 3.17.2
+ * No new changes in 3.18.0
  </notes>
  <contents>
   <dir baseinstalldir="/" name="/">
@@ -1038,5 +1038,50 @@
    <notes>
    </notes>
   </release>
+  <release>
+   <version>
+    <release>3.18.0RC1</release>
+    <api>3.18.0</api>
+   </version>
+   <stability>
+    <release>beta</release>
+    <api>beta</api>
+   </stability>
+   <date>2021-08-18</date>
+   <time>15:23:47</time>
+   <license uri="https://opensource.org/licenses/BSD-3-Clause">3-Clause BSD License</license>
+   <notes>
+   </notes>
+  </release>
+  <release>
+   <version>
+    <release>3.18.0RC2</release>
+    <api>3.18.0</api>
+   </version>
+   <stability>
+    <release>beta</release>
+    <api>beta</api>
+   </stability>
+   <date>2021-08-27</date>
+   <time>14:37:43</time>
+   <license uri="https://opensource.org/licenses/BSD-3-Clause">3-Clause BSD License</license>
+   <notes>
+   </notes>
+  </release>
+  <release>
+   <version>
+    <release>3.18.0</release>
+    <api>3.18.0</api>
+   </version>
+   <stability>
+    <release>stable</release>
+    <api>stable</api>
+   </stability>
+   <date>2021-09-13</date>
+   <time>11:30:58</time>
+   <license uri="https://opensource.org/licenses/BSD-3-Clause">3-Clause BSD License</license>
+   <notes>
+   </notes>
+  </release>
  </changelog>
 </package>
diff --git a/php/ext/google/protobuf/protobuf.c b/php/ext/google/protobuf/protobuf.c
index 888b434..625008f 100644
--- a/php/ext/google/protobuf/protobuf.c
+++ b/php/ext/google/protobuf/protobuf.c
@@ -66,7 +66,7 @@
   // to rebuild it from scratch. When keep_descriptor_pool_after_request==true,
   // we steal the upb_symtab from the global DescriptorPool object just before
   // destroying it.
-  upb_symtab *saved_symtab;
+  upb_symtab *global_symtab;
 
   // Object cache (see interface in protobuf.h).
   HashTable object_cache;
@@ -82,6 +82,13 @@
   HashTable descriptors;
 ZEND_END_MODULE_GLOBALS(protobuf)
 
+void free_protobuf_globals(zend_protobuf_globals *globals) {
+  zend_hash_destroy(&globals->name_msg_cache);
+  zend_hash_destroy(&globals->name_enum_cache);
+  upb_symtab_free(globals->global_symtab);
+  globals->global_symtab = NULL;
+}
+
 ZEND_DECLARE_MODULE_GLOBALS(protobuf)
 
 const zval *get_generated_pool() {
@@ -146,14 +153,14 @@
 //     discouraged by the documentation: https://serverfault.com/a/231660
 
 static PHP_GSHUTDOWN_FUNCTION(protobuf) {
-  if (protobuf_globals->saved_symtab) {
-    upb_symtab_free(protobuf_globals->saved_symtab);
+  if (protobuf_globals->global_symtab) {
+    free_protobuf_globals(protobuf_globals);
   }
 }
 
 static PHP_GINIT_FUNCTION(protobuf) {
   ZVAL_NULL(&protobuf_globals->generated_pool);
-  protobuf_globals->saved_symtab = NULL;
+  protobuf_globals->global_symtab = NULL;
 }
 
 /**
@@ -164,12 +171,15 @@
 static PHP_RINIT_FUNCTION(protobuf) {
   // Create the global generated pool.
   // Reuse the symtab (if any) left to us by the last request.
-  upb_symtab *symtab = PROTOBUF_G(saved_symtab);
+  upb_symtab *symtab = PROTOBUF_G(global_symtab);
+  if (!symtab) {
+    PROTOBUF_G(global_symtab) = symtab = upb_symtab_new();
+    zend_hash_init(&PROTOBUF_G(name_msg_cache), 64, NULL, NULL, 0);
+    zend_hash_init(&PROTOBUF_G(name_enum_cache), 64, NULL, NULL, 0);
+  }
   DescriptorPool_CreateWithSymbolTable(&PROTOBUF_G(generated_pool), symtab);
 
   zend_hash_init(&PROTOBUF_G(object_cache), 64, NULL, NULL, 0);
-  zend_hash_init(&PROTOBUF_G(name_msg_cache), 64, NULL, NULL, 0);
-  zend_hash_init(&PROTOBUF_G(name_enum_cache), 64, NULL, NULL, 0);
   zend_hash_init(&PROTOBUF_G(descriptors), 64, NULL, ZVAL_PTR_DTOR, 0);
 
   return SUCCESS;
@@ -182,15 +192,12 @@
  */
 static PHP_RSHUTDOWN_FUNCTION(protobuf) {
   // Preserve the symtab if requested.
-  if (PROTOBUF_G(keep_descriptor_pool_after_request)) {
-    zval *zv = &PROTOBUF_G(generated_pool);
-    PROTOBUF_G(saved_symtab) = DescriptorPool_Steal(zv);
+  if (!PROTOBUF_G(keep_descriptor_pool_after_request)) {
+    free_protobuf_globals(ZEND_MODULE_GLOBALS_BULK(protobuf));
   }
 
   zval_dtor(&PROTOBUF_G(generated_pool));
   zend_hash_destroy(&PROTOBUF_G(object_cache));
-  zend_hash_destroy(&PROTOBUF_G(name_msg_cache));
-  zend_hash_destroy(&PROTOBUF_G(name_enum_cache));
   zend_hash_destroy(&PROTOBUF_G(descriptors));
 
   return SUCCESS;
@@ -296,7 +303,7 @@
 
 PHP_INI_BEGIN()
 STD_PHP_INI_ENTRY("protobuf.keep_descriptor_pool_after_request", "0",
-                  PHP_INI_SYSTEM, OnUpdateBool,
+                  PHP_INI_ALL, OnUpdateBool,
                   keep_descriptor_pool_after_request, zend_protobuf_globals,
                   protobuf_globals)
 PHP_INI_END()
diff --git a/php/ext/google/protobuf/protobuf.h b/php/ext/google/protobuf/protobuf.h
index 0a71ad0..dbebca3 100644
--- a/php/ext/google/protobuf/protobuf.h
+++ b/php/ext/google/protobuf/protobuf.h
@@ -52,7 +52,7 @@
 #define PROTO_RETURN_VAL zval*
 #endif
 
-// Sine php 8.0, the Object Handlers API was changed to receive zend_object*
+// Since php 8.0, the Object Handlers API was changed to receive zend_object*
 // instead of zval* and zend_string* instead of zval* for property names.
 // https://github.com/php/php-src/blob/php-8.0.0beta1/UPGRADING.INTERNALS#L37-L39
 #if PHP_VERSION_ID < 80000
@@ -74,6 +74,16 @@
 #define PROTO_STRLEN_P(obj) ZSTR_LEN(obj)
 #endif
 
+// In PHP 8.1, several old interfaces are removed:
+// https://github.com/php/php-src/blob/14f599ea7def7c7a59c40aff763ce8b105573e7a/UPGRADING.INTERNALS#L27-L31
+//
+// We now use the new interfaces (zend_ce_arrayaccess and zend_ce_countable).
+// However we have to polyfill zend_ce_countable, which was only introduced in
+// PHP 7.2.0.
+#if PHP_VERSION_ID < 70200
+#define zend_ce_countable spl_ce_Countable
+#endif
+
 ZEND_BEGIN_ARG_INFO(arginfo_void, 0)
 ZEND_END_ARG_INFO()
 
@@ -81,7 +91,7 @@
   ZEND_ARG_INFO(0, value)
 ZEND_END_ARG_INFO()
 
-#define PHP_PROTOBUF_VERSION "3.17.3"
+#define PHP_PROTOBUF_VERSION "3.18.0"
 
 // ptr -> PHP object cache. This is a weak map that caches lazily-created
 // wrapper objects around upb types:
diff --git a/php/tests/GeneratedClassTest.php b/php/tests/GeneratedClassTest.php
index 2b15e42..837f052 100644
--- a/php/tests/GeneratedClassTest.php
+++ b/php/tests/GeneratedClassTest.php
@@ -565,7 +565,7 @@
         $m->setMapInt32Int32($dict);
         $this->assertSame(0, count($m->getMapInt32Int32()));
 
-        $dict = array(5 => 5, 6.1 => 6.1, "7" => "7");
+        $dict = array(5 => 5, 6 => 6.1, "7" => "7");
         $m->setMapInt32Int32($dict);
         $this->assertTrue($m->getMapInt32Int32() instanceof MapField);
         $this->assertSame(3, count($m->getMapInt32Int32()));
diff --git a/php/tests/memory_leak_test.php b/php/tests/memory_leak_test.php
index 1f2d095..ddb8491 100644
--- a/php/tests/memory_leak_test.php
+++ b/php/tests/memory_leak_test.php
@@ -2,9 +2,22 @@
 
 # phpunit has memory leak by itself. Thus, it cannot be used to test memory leak.
 
+class HasDestructor
+{
+  function __construct() {
+    $this->foo = $this;
+  }
+
+  function __destruct() {
+    new Foo\TestMessage();
+  }
+}
+
 require_once('../vendor/autoload.php');
 require_once('test_util.php');
 
+$has_destructor = new HasDestructor();
+
 use Google\Protobuf\Internal\RepeatedField;
 use Google\Protobuf\Internal\GPBType;
 use Foo\TestAny;
diff --git a/php/tests/memory_leak_test.sh b/php/tests/memory_leak_test.sh
new file mode 100755
index 0000000..0b66957
--- /dev/null
+++ b/php/tests/memory_leak_test.sh
@@ -0,0 +1,40 @@
+#!/bin/bash
+
+cd $(dirname $0)
+
+set -ex
+
+PORT=12345
+TIMEOUT=10
+
+./compile_extension.sh
+
+run_test() {
+  echo
+  echo "Running memory leak test, args: $@"
+
+  EXTRA_ARGS=""
+  ARGS="-d xdebug.profiler_enable=0 -d display_errors=on -dextension=../ext/google/protobuf/modules/protobuf.so"
+
+  for i in "$@"; do
+    case $i in
+      --keep_descriptors)
+        EXTRA_ARGS=-dprotobuf.keep_descriptor_pool_after_request=1
+        shift
+        ;;
+    esac
+  done
+
+  export ZEND_DONT_UNLOAD_MODULES=1
+  export USE_ZEND_ALLOC=0
+
+  if valgrind --error-exitcode=1 --leak-check=full --show-leak-kinds=all --errors-for-leak-kinds=all --suppressions=valgrind.supp --num-callers=100 php $ARGS $EXTRA_ARGS memory_leak_test.php; then
+    echo "Memory leak test SUCCEEDED"
+  else
+    echo "Memory leak test FAILED"
+    exit 1
+  fi
+}
+
+run_test
+run_test --keep_descriptors
diff --git a/php/tests/multirequest.sh b/php/tests/multirequest.sh
index ec4a1ae..65bfcfd 100755
--- a/php/tests/multirequest.sh
+++ b/php/tests/multirequest.sh
@@ -5,28 +5,58 @@
 set -e
 
 PORT=12345
+TIMEOUT=10
 
 ./compile_extension.sh
 
-nohup php -d protobuf.keep_descriptor_pool_after_request=1 -dextension=../ext/google/protobuf/modules/protobuf.so -S localhost:$PORT multirequest.php 2>&1 &
+run_test() {
+  echo
+  echo "Running multirequest test, args: $@"
 
-sleep 1
+  RUN_UNDER=""
+  EXTRA_ARGS=""
+  ARGS="-d xdebug.profiler_enable=0 -d display_errors=on -dextension=../ext/google/protobuf/modules/protobuf.so"
 
-wget http://localhost:$PORT/multirequest.result -O multirequest.result
-wget http://localhost:$PORT/multirequest.result -O multirequest.result
+  for i in "$@"; do
+    case $i in
+      --valgrind)
+        RUN_UNDER="valgrind --error-exitcode=1"
+        shift
+        ;;
+      --keep_descriptors)
+        EXTRA_ARGS=-dprotobuf.keep_descriptor_pool_after_request=1
+        shift
+        ;;
+    esac
+  done
 
-pushd ../ext/google/protobuf
-phpize --clean
-popd
+  export ZEND_DONT_UNLOAD_MODULES=1
+  export USE_ZEND_ALLOC=0
+  rm -f nohup.out
+  nohup $RUN_UNDER php $ARGS $EXTRA_ARGS -S localhost:$PORT multirequest.php >nohup.out 2>&1 &
+  PID=$!
 
-PID=`ps | grep "php" | awk '{print $1}'`
-echo $PID
+  if ! timeout $TIMEOUT bash -c "until echo > /dev/tcp/localhost/$PORT; do sleep 0.1; done" > /dev/null 2>&1; then
+    echo "Server failed to come up after $TIMEOUT seconds"
+    cat nohup.out
+    exit 1
+  fi
 
-if [[ -z "$PID" ]]
-then
-  echo "Failed"
-  exit 1
-else
-  kill $PID
-  echo "Succeeded"
-fi
+  seq 2 | xargs -I{} wget -nv http://localhost:$PORT/multirequest.result -O multirequest{}.result
+  REQUESTS_SUCCEEDED=$?
+
+
+  if kill $PID > /dev/null 2>&1 && [[ $REQUESTS_SUCCEEDED == "0" ]]; then
+    wait
+    echo "Multirequest test SUCCEEDED"
+  else
+    echo "Multirequest test FAILED"
+    cat nohup.out
+    exit 1
+  fi
+}
+
+run_test
+run_test --keep_descriptors
+run_test --valgrind
+run_test --valgrind --keep_descriptors
diff --git a/php/tests/valgrind.supp b/php/tests/valgrind.supp
index e83b0a3..8d31466 100644
--- a/php/tests/valgrind.supp
+++ b/php/tests/valgrind.supp
@@ -10,3 +10,24 @@
    obj:/usr/bin/php7.3
    fun:__scandir64_tail
 }
+
+{
+   PHP_ModuleLoadingLeaks
+   Memcheck:Leak
+   ...
+   fun:php_module_startup
+}
+
+{
+   PHP_ModuleLoadingLeaks
+   Memcheck:Leak
+   ...
+   fun:php_module_startup
+}
+
+{
+   PHP_ModuleLoadingLeaks2
+   Memcheck:Leak
+   ...
+   fun:php_load_shlib
+}
diff --git a/protobuf_version.bzl b/protobuf_version.bzl
index dd1f797..f3ef083 100644
--- a/protobuf_version.bzl
+++ b/protobuf_version.bzl
@@ -1 +1 @@
-PROTOBUF_VERSION = '3.17.3'
+PROTOBUF_VERSION = '3.18.0'
diff --git a/protoc-artifacts/pom.xml b/protoc-artifacts/pom.xml
index 4eec6e3..93b118b 100644
--- a/protoc-artifacts/pom.xml
+++ b/protoc-artifacts/pom.xml
@@ -8,7 +8,7 @@
   </parent>
   <groupId>com.google.protobuf</groupId>
   <artifactId>protoc</artifactId>
-  <version>3.17.3</version>
+  <version>3.18.0</version>
   <packaging>pom</packaging>
   <name>Protobuf Compiler</name>
   <description>
diff --git a/python/MANIFEST.in b/python/MANIFEST.in
index 5fb0192..a81760f 100644
--- a/python/MANIFEST.in
+++ b/python/MANIFEST.in
@@ -15,3 +15,5 @@
 global-exclude *.pyc
 global-exclude *.pyo
 global-exclude *.so
+
+include LICENSE
diff --git a/python/google/protobuf/__init__.py b/python/google/protobuf/__init__.py
index 496df6a..cb47404 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.17.3'
+__version__ = '3.18.0'
diff --git a/python/google/protobuf/descriptor.py b/python/google/protobuf/descriptor.py
index 0f7bd17..61c242f 100644
--- a/python/google/protobuf/descriptor.py
+++ b/python/google/protobuf/descriptor.py
@@ -951,7 +951,7 @@
     public_dependencies (list[FileDescriptor]): A subset of
       :attr:`dependencies`, which were declared as "public".
     message_types_by_name (dict(str, Descriptor)): Mapping from message names
-      to their :class:`Desctiptor`.
+      to their :class:`Descriptor`.
     enum_types_by_name (dict(str, EnumDescriptor)): Mapping from enum names to
       their :class:`EnumDescriptor`.
     extensions_by_name (dict(str, FieldDescriptor)): Mapping from extension
diff --git a/python/google/protobuf/internal/api_implementation.cc b/python/google/protobuf/internal/api_implementation.cc
index 2a7f41d..6532a81 100644
--- a/python/google/protobuf/internal/api_implementation.cc
+++ b/python/google/protobuf/internal/api_implementation.cc
@@ -77,7 +77,6 @@
     "constants defined in C, such that one can set defaults at compilation\n"
     "(e.g. with blaze flag --copt=-DPYTHON_PROTO2_CPP_IMPL_V2).";
 
-#if PY_MAJOR_VERSION >= 3
 static struct PyModuleDef _module = {PyModuleDef_HEAD_INIT,
                                      kModuleName,
                                      kModuleDocstring,
@@ -87,38 +86,22 @@
                                      NULL,
                                      NULL,
                                      NULL};
-#define INITFUNC PyInit__api_implementation
-#define INITFUNC_ERRORVAL NULL
-#else
-#define INITFUNC init_api_implementation
-#define INITFUNC_ERRORVAL
-#endif
 
 extern "C" {
-PyMODINIT_FUNC INITFUNC() {
-#if PY_MAJOR_VERSION >= 3
+PyMODINIT_FUNC PyInit__api_implementation() {
   PyObject* module = PyModule_Create(&_module);
-#else
-  PyObject* module = Py_InitModule3(const_cast<char*>(kModuleName), NULL,
-                                    const_cast<char*>(kModuleDocstring));
-#endif
   if (module == NULL) {
-    return INITFUNC_ERRORVAL;
+    return NULL;
   }
 
   // Adds the module variable "api_version".
   if (PyModule_AddIntConstant(module, const_cast<char*>(kImplVersionName),
-                              kImplVersion))
-#if PY_MAJOR_VERSION < 3
-    return;
-#else
-  {
+                              kImplVersion)) {
     Py_DECREF(module);
     return NULL;
   }
 
   return module;
-#endif
 }
 }
 
diff --git a/python/google/protobuf/internal/containers.py b/python/google/protobuf/internal/containers.py
index 9279349..f0c06df 100644
--- a/python/google/protobuf/internal/containers.py
+++ b/python/google/protobuf/internal/containers.py
@@ -42,149 +42,7 @@
 
 __author__ = '[email protected] (Petar Petrov)'
 
-import sys
-try:
-  # This fallback applies for all versions of Python before 3.3
-  import collections.abc as collections_abc
-except ImportError:
-  import collections as collections_abc
-
-if sys.version_info[0] < 3:
-  # We would use collections_abc.MutableMapping all the time, but in Python 2
-  # it doesn't define __slots__.  This causes two significant problems:
-  #
-  # 1. we can't disallow arbitrary attribute assignment, even if our derived
-  #    classes *do* define __slots__.
-  #
-  # 2. we can't safely derive a C type from it without __slots__ defined (the
-  #    interpreter expects to find a dict at tp_dictoffset, which we can't
-  #    robustly provide.  And we don't want an instance dict anyway.
-  #
-  # So this is the Python 2.7 definition of Mapping/MutableMapping functions
-  # verbatim, except that:
-  # 1. We declare __slots__.
-  # 2. We don't declare this as a virtual base class.  The classes defined
-  #    in collections_abc are the interesting base classes, not us.
-  #
-  # Note: deriving from object is critical.  It is the only thing that makes
-  # this a true type, allowing us to derive from it in C++ cleanly and making
-  # __slots__ properly disallow arbitrary element assignment.
-
-  class Mapping(object):
-    __slots__ = ()
-
-    def get(self, key, default=None):
-      try:
-        return self[key]
-      except KeyError:
-        return default
-
-    def __contains__(self, key):
-      try:
-        self[key]
-      except KeyError:
-        return False
-      else:
-        return True
-
-    def iterkeys(self):
-      return iter(self)
-
-    def itervalues(self):
-      for key in self:
-        yield self[key]
-
-    def iteritems(self):
-      for key in self:
-        yield (key, self[key])
-
-    def keys(self):
-      return list(self)
-
-    def items(self):
-      return [(key, self[key]) for key in self]
-
-    def values(self):
-      return [self[key] for key in self]
-
-    # Mappings are not hashable by default, but subclasses can change this
-    __hash__ = None
-
-    def __eq__(self, other):
-      if not isinstance(other, collections_abc.Mapping):
-        return NotImplemented
-      return dict(self.items()) == dict(other.items())
-
-    def __ne__(self, other):
-      return not (self == other)
-
-  class MutableMapping(Mapping):
-    __slots__ = ()
-
-    __marker = object()
-
-    def pop(self, key, default=__marker):
-      try:
-        value = self[key]
-      except KeyError:
-        if default is self.__marker:
-          raise
-        return default
-      else:
-        del self[key]
-        return value
-
-    def popitem(self):
-      try:
-        key = next(iter(self))
-      except StopIteration:
-        raise KeyError
-      value = self[key]
-      del self[key]
-      return key, value
-
-    def clear(self):
-      try:
-        while True:
-          self.popitem()
-      except KeyError:
-        pass
-
-    def update(*args, **kwds):
-      if len(args) > 2:
-        raise TypeError("update() takes at most 2 positional "
-                        "arguments ({} given)".format(len(args)))
-      elif not args:
-        raise TypeError("update() takes at least 1 argument (0 given)")
-      self = args[0]
-      other = args[1] if len(args) >= 2 else ()
-
-      if isinstance(other, Mapping):
-        for key in other:
-          self[key] = other[key]
-      elif hasattr(other, "keys"):
-        for key in other.keys():
-          self[key] = other[key]
-      else:
-        for key, value in other:
-          self[key] = value
-      for key, value in kwds.items():
-        self[key] = value
-
-    def setdefault(self, key, default=None):
-      try:
-        return self[key]
-      except KeyError:
-        self[key] = default
-      return default
-
-  collections_abc.Mapping.register(Mapping)
-  collections_abc.MutableMapping.register(MutableMapping)
-
-else:
-  # In Python 3 we can just use MutableMapping directly, because it defines
-  # __slots__.
-  MutableMapping = collections_abc.MutableMapping
+import collections.abc
 
 
 class BaseContainer(object):
@@ -235,7 +93,7 @@
     self._values.reverse()
 
 
-collections_abc.MutableSequence.register(BaseContainer)
+collections.abc.MutableSequence.register(BaseContainer)
 
 
 class RepeatedScalarFieldContainer(BaseContainer):
@@ -458,7 +316,7 @@
     return self._values == other._values
 
 
-class ScalarMap(MutableMapping):
+class ScalarMap(collections.abc.MutableMapping):
 
   """Simple, type-checked, dict-like container for holding repeated scalars."""
 
@@ -548,7 +406,7 @@
     return self._entry_descriptor._concrete_class
 
 
-class MessageMap(MutableMapping):
+class MessageMap(collections.abc.MutableMapping):
 
   """Simple, type-checked, dict-like container for with submessage values."""
 
diff --git a/python/google/protobuf/internal/text_format_test.py b/python/google/protobuf/internal/text_format_test.py
index 82b98c1..ec1ad52 100644
--- a/python/google/protobuf/internal/text_format_test.py
+++ b/python/google/protobuf/internal/text_format_test.py
@@ -520,6 +520,35 @@
         '  type: TYPE_INT32\n'
         '  oneof_index: 0\n'
         '}\n'
+        'field {\n'
+        '  name: "map_field"\n'
+        '  number: 3\n'
+        '  label: LABEL_REPEATED\n'
+        '  type: TYPE_MESSAGE\n'
+        '  type_name: ".protobuf_unittest.TestMessageWithCustomOptions.'
+        'MapFieldEntry"\n'
+        '  options {\n'
+        '    [protobuf_unittest.field_opt1]: 12345\n'
+        '  }\n'
+        '}\n'
+        'nested_type {\n'
+        '  name: "MapFieldEntry"\n'
+        '  field {\n'
+        '    name: "key"\n'
+        '    number: 1\n'
+        '    label: LABEL_OPTIONAL\n'
+        '    type: TYPE_STRING\n'
+        '  }\n'
+        '  field {\n'
+        '    name: "value"\n'
+        '    number: 2\n'
+        '    label: LABEL_OPTIONAL\n'
+        '    type: TYPE_STRING\n'
+        '  }\n'
+        '  options {\n'
+        '    map_entry: true\n'
+        '  }\n'
+        '}\n'
         'enum_type {\n'
         '  name: "AnEnum"\n'
         '  value {\n'
diff --git a/python/google/protobuf/internal/well_known_types.py b/python/google/protobuf/internal/well_known_types.py
index f14f152..30ff125 100644
--- a/python/google/protobuf/internal/well_known_types.py
+++ b/python/google/protobuf/internal/well_known_types.py
@@ -41,16 +41,10 @@
 __author__ = '[email protected] (Jie Luo)'
 
 import calendar
+import collections.abc
 from datetime import datetime
 from datetime import timedelta
 
-try:
-  # Since python 3
-  import collections.abc as collections_abc
-except ImportError:
-  # Won't work after python 3.8
-  import collections as collections_abc
-
 from google.protobuf.descriptor import FieldDescriptor
 
 _TIMESTAMPFOMAT = '%Y-%m-%dT%H:%M:%S'
@@ -806,7 +800,7 @@
     for key, value in dictionary.items():
       _SetStructValue(self.fields[key], value)
 
-collections_abc.MutableMapping.register(Struct)
+collections.abc.MutableMapping.register(Struct)
 
 
 class ListValue(object):
@@ -852,7 +846,7 @@
     list_value.Clear()
     return list_value
 
-collections_abc.MutableSequence.register(ListValue)
+collections.abc.MutableSequence.register(ListValue)
 
 
 WKTBASES = {
diff --git a/python/google/protobuf/pyext/descriptor.cc b/python/google/protobuf/pyext/descriptor.cc
index 8c326ef..9708b84 100644
--- a/python/google/protobuf/pyext/descriptor.cc
+++ b/python/google/protobuf/pyext/descriptor.cc
@@ -49,22 +49,12 @@
 #include <google/protobuf/pyext/scoped_pyobject_ptr.h>
 #include <google/protobuf/stubs/hash.h>
 
-#if PY_MAJOR_VERSION >= 3
-  #define PyString_FromStringAndSize PyUnicode_FromStringAndSize
-  #define PyString_Check PyUnicode_Check
-  #define PyString_InternFromString PyUnicode_InternFromString
-  #define PyInt_FromLong PyLong_FromLong
-  #define PyInt_FromSize_t PyLong_FromSize_t
-  #if PY_VERSION_HEX < 0x03030000
-    #error "Python 3.0 - 3.2 are not supported."
-  #endif
 #define PyString_AsStringAndSize(ob, charpp, sizep)                           \
   (PyUnicode_Check(ob) ? ((*(charpp) = const_cast<char*>(                     \
                                PyUnicode_AsUTF8AndSize(ob, (sizep)))) == NULL \
                               ? -1                                            \
                               : 0)                                            \
                        : PyBytes_AsStringAndSize(ob, (charpp), (sizep)))
-#endif
 
 namespace google {
 namespace protobuf {
@@ -79,7 +69,7 @@
 std::unordered_map<const void*, PyObject*>* interned_descriptors;
 
 PyObject* PyString_FromCppString(const std::string& str) {
-  return PyString_FromStringAndSize(str.c_str(), str.size());
+  return PyUnicode_FromStringAndSize(str.c_str(), str.size());
 }
 
 // Check that the calling Python code is the global scope of a _pb2.py module.
@@ -565,8 +555,8 @@
 
   for (int i = 0; i < descriptor->extension_range_count(); i++) {
     const Descriptor::ExtensionRange* range = descriptor->extension_range(i);
-    PyObject* start = PyInt_FromLong(range->start);
-    PyObject* end = PyInt_FromLong(range->end);
+    PyObject* start = PyLong_FromLong(range->start);
+    PyObject* end = PyLong_FromLong(range->end);
     PyList_SetItem(range_list, i, PyTuple_Pack(2, start, end));
   }
 
@@ -640,7 +630,7 @@
 }
 
 static PyObject* GetSyntax(PyBaseDescriptor *self, void *closure) {
-  return PyString_InternFromString(
+  return PyUnicode_InternFromString(
       FileDescriptor::SyntaxName(_GetDescriptor(self)->file()->syntax()));
 }
 
@@ -767,23 +757,23 @@
 }
 
 static PyObject* GetType(PyBaseDescriptor *self, void *closure) {
-  return PyInt_FromLong(_GetDescriptor(self)->type());
+  return PyLong_FromLong(_GetDescriptor(self)->type());
 }
 
 static PyObject* GetCppType(PyBaseDescriptor *self, void *closure) {
-  return PyInt_FromLong(_GetDescriptor(self)->cpp_type());
+  return PyLong_FromLong(_GetDescriptor(self)->cpp_type());
 }
 
 static PyObject* GetLabel(PyBaseDescriptor *self, void *closure) {
-  return PyInt_FromLong(_GetDescriptor(self)->label());
+  return PyLong_FromLong(_GetDescriptor(self)->label());
 }
 
 static PyObject* GetNumber(PyBaseDescriptor *self, void *closure) {
-  return PyInt_FromLong(_GetDescriptor(self)->number());
+  return PyLong_FromLong(_GetDescriptor(self)->number());
 }
 
 static PyObject* GetIndex(PyBaseDescriptor *self, void *closure) {
-  return PyInt_FromLong(_GetDescriptor(self)->index());
+  return PyLong_FromLong(_GetDescriptor(self)->index());
 }
 
 static PyObject* GetID(PyBaseDescriptor *self, void *closure) {
@@ -809,7 +799,7 @@
   switch (_GetDescriptor(self)->cpp_type()) {
     case FieldDescriptor::CPPTYPE_INT32: {
       int32_t value = _GetDescriptor(self)->default_value_int32();
-      result = PyInt_FromLong(value);
+      result = PyLong_FromLong(value);
       break;
     }
     case FieldDescriptor::CPPTYPE_INT64: {
@@ -819,7 +809,7 @@
     }
     case FieldDescriptor::CPPTYPE_UINT32: {
       uint32_t value = _GetDescriptor(self)->default_value_uint32();
-      result = PyInt_FromSize_t(value);
+      result = PyLong_FromSsize_t(value);
       break;
     }
     case FieldDescriptor::CPPTYPE_UINT64: {
@@ -850,7 +840,7 @@
     case FieldDescriptor::CPPTYPE_ENUM: {
       const EnumValueDescriptor* value =
           _GetDescriptor(self)->default_value_enum();
-      result = PyInt_FromLong(value->number());
+      result = PyLong_FromLong(value->number());
       break;
     }
     case FieldDescriptor::CPPTYPE_MESSAGE: {
@@ -1222,11 +1212,11 @@
 }
 
 static PyObject* GetNumber(PyBaseDescriptor *self, void *closure) {
-  return PyInt_FromLong(_GetDescriptor(self)->number());
+  return PyLong_FromLong(_GetDescriptor(self)->number());
 }
 
 static PyObject* GetIndex(PyBaseDescriptor *self, void *closure) {
-  return PyInt_FromLong(_GetDescriptor(self)->index());
+  return PyLong_FromLong(_GetDescriptor(self)->index());
 }
 
 static PyObject* GetType(PyBaseDescriptor *self, void *closure) {
@@ -1418,7 +1408,7 @@
 }
 
 static PyObject* GetSyntax(PyFileDescriptor *self, void *closure) {
-  return PyString_InternFromString(
+  return PyUnicode_InternFromString(
       FileDescriptor::SyntaxName(_GetDescriptor(self)->syntax()));
 }
 
@@ -1550,7 +1540,7 @@
 }
 
 static PyObject* GetIndex(PyBaseDescriptor *self, void *closure) {
-  return PyInt_FromLong(_GetDescriptor(self)->index());
+  return PyLong_FromLong(_GetDescriptor(self)->index());
 }
 
 static PyObject* GetFields(PyBaseDescriptor* self, void *closure) {
@@ -1676,7 +1666,7 @@
 }
 
 static PyObject* GetIndex(PyBaseDescriptor *self, void *closure) {
-  return PyInt_FromLong(_GetDescriptor(self)->index());
+  return PyLong_FromLong(_GetDescriptor(self)->index());
 }
 
 static PyObject* GetMethods(PyBaseDescriptor* self, void *closure) {
@@ -1799,7 +1789,7 @@
 }
 
 static PyObject* GetIndex(PyBaseDescriptor *self, void *closure) {
-  return PyInt_FromLong(_GetDescriptor(self)->index());
+  return PyLong_FromLong(_GetDescriptor(self)->index());
 }
 
 static PyObject* GetContainingService(PyBaseDescriptor *self, void *closure) {
@@ -1890,7 +1880,7 @@
                           const EnumDescriptor* enum_descriptor) {
   for (int i = 0; i < enum_descriptor->value_count(); ++i) {
     const EnumValueDescriptor* value = enum_descriptor->value(i);
-    ScopedPyObjectPtr obj(PyInt_FromLong(value->number()));
+    ScopedPyObjectPtr obj(PyLong_FromLong(value->number()));
     if (obj == NULL) {
       return false;
     }
@@ -1903,7 +1893,7 @@
 }
 
 static bool AddIntConstant(PyTypeObject *type, const char* name, int value) {
-  ScopedPyObjectPtr obj(PyInt_FromLong(value));
+  ScopedPyObjectPtr obj(PyLong_FromLong(value));
   if (PyDict_SetItemString(type->tp_dict, name, obj.get()) < 0) {
     return false;
   }
diff --git a/python/google/protobuf/pyext/descriptor_containers.cc b/python/google/protobuf/pyext/descriptor_containers.cc
index c6ec258..b084f5b 100644
--- a/python/google/protobuf/pyext/descriptor_containers.cc
+++ b/python/google/protobuf/pyext/descriptor_containers.cc
@@ -57,20 +57,12 @@
 #include <google/protobuf/pyext/descriptor.h>
 #include <google/protobuf/pyext/scoped_pyobject_ptr.h>
 
-#if PY_MAJOR_VERSION >= 3
-  #define PyString_FromStringAndSize PyUnicode_FromStringAndSize
-  #define PyString_FromFormat PyUnicode_FromFormat
-  #define PyInt_FromLong PyLong_FromLong
-  #if PY_VERSION_HEX < 0x03030000
-    #error "Python 3.0 - 3.2 are not supported."
-  #endif
 #define PyString_AsStringAndSize(ob, charpp, sizep)                           \
   (PyUnicode_Check(ob) ? ((*(charpp) = const_cast<char*>(                     \
                                PyUnicode_AsUTF8AndSize(ob, (sizep)))) == NULL \
                               ? -1                                            \
                               : 0)                                            \
                        : PyBytes_AsStringAndSize(ob, (charpp), (sizep)))
-#endif
 
 namespace google {
 namespace protobuf {
@@ -232,18 +224,18 @@
     case PyContainer::KIND_BYNAME:
       {
       const std::string& name(self->container_def->get_item_name_fn(item));
-      return PyString_FromStringAndSize(name.c_str(), name.size());
+      return PyUnicode_FromStringAndSize(name.c_str(), name.size());
       }
     case PyContainer::KIND_BYCAMELCASENAME:
       {
       const std::string& name(
           self->container_def->get_item_camelcase_name_fn(item));
-      return PyString_FromStringAndSize(name.c_str(), name.size());
+      return PyUnicode_FromStringAndSize(name.c_str(), name.size());
       }
     case PyContainer::KIND_BYNUMBER:
       {
         int value = self->container_def->get_item_number_fn(item);
-        return PyInt_FromLong(value);
+        return PyLong_FromLong(value);
       }
     default:
       PyErr_SetNone(PyExc_NotImplementedError);
@@ -320,8 +312,8 @@
       kind = "mapping by number";
       break;
   }
-  return PyString_FromFormat(
-      "<%s %s>", self->container_def->mapping_name, kind);
+  return PyUnicode_FromFormat("<%s %s>", self->container_def->mapping_name,
+                              kind);
 }
 
 extern PyTypeObject DescriptorMapping_Type;
@@ -678,7 +670,7 @@
     PyErr_SetNone(PyExc_ValueError);
     return NULL;
   } else {
-    return PyInt_FromLong(position);
+    return PyLong_FromLong(position);
   }
 }
 // Implements "list.__contains__()": is the object in the sequence.
@@ -696,9 +688,9 @@
 static PyObject* Count(PyContainer* self, PyObject* item) {
   int position = Find(self, item);
   if (position < 0) {
-    return PyInt_FromLong(0);
+    return PyLong_FromLong(0);
   } else {
-    return PyInt_FromLong(1);
+    return PyLong_FromLong(1);
   }
 }
 
diff --git a/python/google/protobuf/pyext/descriptor_pool.cc b/python/google/protobuf/pyext/descriptor_pool.cc
index 7154d31..5ec6269 100644
--- a/python/google/protobuf/pyext/descriptor_pool.cc
+++ b/python/google/protobuf/pyext/descriptor_pool.cc
@@ -43,18 +43,12 @@
 #include <google/protobuf/pyext/scoped_pyobject_ptr.h>
 #include <google/protobuf/stubs/hash.h>
 
-#if PY_MAJOR_VERSION >= 3
-  #define PyString_FromStringAndSize PyUnicode_FromStringAndSize
-  #if PY_VERSION_HEX < 0x03030000
-    #error "Python 3.0 - 3.2 are not supported."
-  #endif
 #define PyString_AsStringAndSize(ob, charpp, sizep)                           \
   (PyUnicode_Check(ob) ? ((*(charpp) = const_cast<char*>(                     \
                                PyUnicode_AsUTF8AndSize(ob, (sizep)))) == NULL \
                               ? -1                                            \
                               : 0)                                            \
                        : PyBytes_AsStringAndSize(ob, (charpp), (sizep)))
-#endif
 
 namespace google {
 namespace protobuf {
diff --git a/python/google/protobuf/pyext/extension_dict.cc b/python/google/protobuf/pyext/extension_dict.cc
index 37b414c..b36c723 100644
--- a/python/google/protobuf/pyext/extension_dict.cc
+++ b/python/google/protobuf/pyext/extension_dict.cc
@@ -49,17 +49,12 @@
 #include <google/protobuf/pyext/repeated_scalar_container.h>
 #include <google/protobuf/pyext/scoped_pyobject_ptr.h>
 
-#if PY_MAJOR_VERSION >= 3
-  #if PY_VERSION_HEX < 0x03030000
-    #error "Python 3.0 - 3.2 are not supported."
-  #endif
 #define PyString_AsStringAndSize(ob, charpp, sizep)                           \
   (PyUnicode_Check(ob) ? ((*(charpp) = const_cast<char*>(                     \
                                PyUnicode_AsUTF8AndSize(ob, (sizep)))) == NULL \
                               ? -1                                            \
                               : 0)                                            \
                        : PyBytes_AsStringAndSize(ob, (charpp), (sizep)))
-#endif
 
 namespace google {
 namespace protobuf {
diff --git a/python/google/protobuf/pyext/field.cc b/python/google/protobuf/pyext/field.cc
index 1afd458..5eab3ef 100644
--- a/python/google/protobuf/pyext/field.cc
+++ b/python/google/protobuf/pyext/field.cc
@@ -34,10 +34,6 @@
 #include <google/protobuf/pyext/descriptor.h>
 #include <google/protobuf/pyext/message.h>
 
-#if PY_MAJOR_VERSION >= 3
-  #define PyString_FromFormat PyUnicode_FromFormat
-#endif
-
 namespace google {
 namespace protobuf {
 namespace python {
@@ -45,8 +41,8 @@
 namespace field {
 
 static PyObject* Repr(PyMessageFieldProperty* self) {
-  return PyString_FromFormat("<field property '%s'>",
-                             self->field_descriptor->full_name().c_str());
+  return PyUnicode_FromFormat("<field property '%s'>",
+                              self->field_descriptor->full_name().c_str());
 }
 
 static PyObject* DescrGet(PyMessageFieldProperty* self, PyObject* obj,
@@ -74,8 +70,8 @@
 }
 
 static PyObject* GetDoc(PyMessageFieldProperty* self, void* closure) {
-  return PyString_FromFormat("Field %s",
-                             self->field_descriptor->full_name().c_str());
+  return PyUnicode_FromFormat("Field %s",
+                              self->field_descriptor->full_name().c_str());
 }
 
 static PyGetSetDef Getters[] = {
diff --git a/python/google/protobuf/pyext/map_container.cc b/python/google/protobuf/pyext/map_container.cc
index 1c2c526..053a78e 100644
--- a/python/google/protobuf/pyext/map_container.cc
+++ b/python/google/protobuf/pyext/map_container.cc
@@ -46,11 +46,6 @@
 #include <google/protobuf/pyext/scoped_pyobject_ptr.h>
 #include <google/protobuf/stubs/map_util.h>
 
-#if PY_MAJOR_VERSION >= 3
-  #define PyInt_FromLong PyLong_FromLong
-  #define PyInt_FromSize_t PyLong_FromSize_t
-#endif
-
 namespace google {
 namespace protobuf {
 namespace python {
@@ -177,11 +172,11 @@
       self->parent_field_descriptor->message_type()->map_key();
   switch (field_descriptor->cpp_type()) {
     case FieldDescriptor::CPPTYPE_INT32:
-      return PyInt_FromLong(key.GetInt32Value());
+      return PyLong_FromLong(key.GetInt32Value());
     case FieldDescriptor::CPPTYPE_INT64:
       return PyLong_FromLongLong(key.GetInt64Value());
     case FieldDescriptor::CPPTYPE_UINT32:
-      return PyInt_FromSize_t(key.GetUInt32Value());
+      return PyLong_FromSize_t(key.GetUInt32Value());
     case FieldDescriptor::CPPTYPE_UINT64:
       return PyLong_FromUnsignedLongLong(key.GetUInt64Value());
     case FieldDescriptor::CPPTYPE_BOOL:
@@ -203,11 +198,11 @@
       self->parent_field_descriptor->message_type()->map_value();
   switch (field_descriptor->cpp_type()) {
     case FieldDescriptor::CPPTYPE_INT32:
-      return PyInt_FromLong(value.GetInt32Value());
+      return PyLong_FromLong(value.GetInt32Value());
     case FieldDescriptor::CPPTYPE_INT64:
       return PyLong_FromLongLong(value.GetInt64Value());
     case FieldDescriptor::CPPTYPE_UINT32:
-      return PyInt_FromSize_t(value.GetUInt32Value());
+      return PyLong_FromSize_t(value.GetUInt32Value());
     case FieldDescriptor::CPPTYPE_UINT64:
       return PyLong_FromUnsignedLongLong(value.GetUInt64Value());
     case FieldDescriptor::CPPTYPE_FLOAT:
@@ -219,7 +214,7 @@
     case FieldDescriptor::CPPTYPE_STRING:
       return ToStringObject(field_descriptor, value.GetStringValue());
     case FieldDescriptor::CPPTYPE_ENUM:
-      return PyInt_FromLong(value.GetEnumValue());
+      return PyLong_FromLong(value.GetEnumValue());
     default:
       PyErr_Format(
           PyExc_SystemError, "Couldn't convert type %d to value",
@@ -550,73 +545,21 @@
     {NULL, NULL},
 };
 
-PyTypeObject *ScalarMapContainer_Type;
-#if PY_MAJOR_VERSION >= 3
-  static PyType_Slot ScalarMapContainer_Type_slots[] = {
-      {Py_tp_dealloc, (void *)ScalarMapDealloc},
-      {Py_mp_length, (void *)MapReflectionFriend::Length},
-      {Py_mp_subscript, (void *)MapReflectionFriend::ScalarMapGetItem},
-      {Py_mp_ass_subscript, (void *)MapReflectionFriend::ScalarMapSetItem},
-      {Py_tp_methods, (void *)ScalarMapMethods},
-      {Py_tp_iter, (void *)MapReflectionFriend::GetIterator},
-      {Py_tp_repr, (void *)MapReflectionFriend::ScalarMapToStr},
-      {0, 0},
-  };
+PyTypeObject* ScalarMapContainer_Type;
+static PyType_Slot ScalarMapContainer_Type_slots[] = {
+    {Py_tp_dealloc, (void*)ScalarMapDealloc},
+    {Py_mp_length, (void*)MapReflectionFriend::Length},
+    {Py_mp_subscript, (void*)MapReflectionFriend::ScalarMapGetItem},
+    {Py_mp_ass_subscript, (void*)MapReflectionFriend::ScalarMapSetItem},
+    {Py_tp_methods, (void*)ScalarMapMethods},
+    {Py_tp_iter, (void*)MapReflectionFriend::GetIterator},
+    {Py_tp_repr, (void*)MapReflectionFriend::ScalarMapToStr},
+    {0, 0},
+};
 
-  PyType_Spec ScalarMapContainer_Type_spec = {
-      FULL_MODULE_NAME ".ScalarMapContainer",
-      sizeof(MapContainer),
-      0,
-      Py_TPFLAGS_DEFAULT,
-      ScalarMapContainer_Type_slots
-  };
-#else
-  static PyMappingMethods ScalarMapMappingMethods = {
-    MapReflectionFriend::Length,             // mp_length
-    MapReflectionFriend::ScalarMapGetItem,   // mp_subscript
-    MapReflectionFriend::ScalarMapSetItem,   // mp_ass_subscript
-  };
-
-  PyTypeObject _ScalarMapContainer_Type = {
-    PyVarObject_HEAD_INIT(&PyType_Type, 0)
-    FULL_MODULE_NAME ".ScalarMapContainer",  //  tp_name
-    sizeof(MapContainer),                //  tp_basicsize
-    0,                                   //  tp_itemsize
-    ScalarMapDealloc,                    //  tp_dealloc
-    0,                                   //  tp_print
-    0,                                   //  tp_getattr
-    0,                                   //  tp_setattr
-    0,                                   //  tp_compare
-    MapReflectionFriend::ScalarMapToStr,  //  tp_repr
-    0,                                   //  tp_as_number
-    0,                                   //  tp_as_sequence
-    &ScalarMapMappingMethods,            //  tp_as_mapping
-    0,                                   //  tp_hash
-    0,                                   //  tp_call
-    0,                                   //  tp_str
-    0,                                   //  tp_getattro
-    0,                                   //  tp_setattro
-    0,                                   //  tp_as_buffer
-    Py_TPFLAGS_DEFAULT,                  //  tp_flags
-    "A scalar map container",            //  tp_doc
-    0,                                   //  tp_traverse
-    0,                                   //  tp_clear
-    0,                                   //  tp_richcompare
-    0,                                   //  tp_weaklistoffset
-    MapReflectionFriend::GetIterator,    //  tp_iter
-    0,                                   //  tp_iternext
-    ScalarMapMethods,                    //  tp_methods
-    0,                                   //  tp_members
-    0,                                   //  tp_getset
-    0,                                   //  tp_base
-    0,                                   //  tp_dict
-    0,                                   //  tp_descr_get
-    0,                                   //  tp_descr_set
-    0,                                   //  tp_dictoffset
-    0,                                   //  tp_init
-  };
-#endif
-
+PyType_Spec ScalarMapContainer_Type_spec = {
+    FULL_MODULE_NAME ".ScalarMapContainer", sizeof(MapContainer), 0,
+    Py_TPFLAGS_DEFAULT, ScalarMapContainer_Type_slots};
 
 // MessageMap //////////////////////////////////////////////////////////////////
 
@@ -819,72 +762,20 @@
     {NULL, NULL},
 };
 
-PyTypeObject *MessageMapContainer_Type;
-#if PY_MAJOR_VERSION >= 3
-  static PyType_Slot MessageMapContainer_Type_slots[] = {
-      {Py_tp_dealloc, (void *)MessageMapDealloc},
-      {Py_mp_length, (void *)MapReflectionFriend::Length},
-      {Py_mp_subscript, (void *)MapReflectionFriend::MessageMapGetItem},
-      {Py_mp_ass_subscript, (void *)MapReflectionFriend::MessageMapSetItem},
-      {Py_tp_methods, (void *)MessageMapMethods},
-      {Py_tp_iter, (void *)MapReflectionFriend::GetIterator},
-      {Py_tp_repr, (void *)MapReflectionFriend::MessageMapToStr},
-      {0, 0}
-  };
+PyTypeObject* MessageMapContainer_Type;
+static PyType_Slot MessageMapContainer_Type_slots[] = {
+    {Py_tp_dealloc, (void*)MessageMapDealloc},
+    {Py_mp_length, (void*)MapReflectionFriend::Length},
+    {Py_mp_subscript, (void*)MapReflectionFriend::MessageMapGetItem},
+    {Py_mp_ass_subscript, (void*)MapReflectionFriend::MessageMapSetItem},
+    {Py_tp_methods, (void*)MessageMapMethods},
+    {Py_tp_iter, (void*)MapReflectionFriend::GetIterator},
+    {Py_tp_repr, (void*)MapReflectionFriend::MessageMapToStr},
+    {0, 0}};
 
-  PyType_Spec MessageMapContainer_Type_spec = {
-      FULL_MODULE_NAME ".MessageMapContainer",
-      sizeof(MessageMapContainer),
-      0,
-      Py_TPFLAGS_DEFAULT,
-      MessageMapContainer_Type_slots
-  };
-#else
-  static PyMappingMethods MessageMapMappingMethods = {
-    MapReflectionFriend::Length,              // mp_length
-    MapReflectionFriend::MessageMapGetItem,   // mp_subscript
-    MapReflectionFriend::MessageMapSetItem,   // mp_ass_subscript
-  };
-
-  PyTypeObject _MessageMapContainer_Type = {
-    PyVarObject_HEAD_INIT(&PyType_Type, 0)
-    FULL_MODULE_NAME ".MessageMapContainer",  //  tp_name
-    sizeof(MessageMapContainer),         //  tp_basicsize
-    0,                                   //  tp_itemsize
-    MessageMapDealloc,                   //  tp_dealloc
-    0,                                   //  tp_print
-    0,                                   //  tp_getattr
-    0,                                   //  tp_setattr
-    0,                                   //  tp_compare
-    MapReflectionFriend::MessageMapToStr,  //  tp_repr
-    0,                                   //  tp_as_number
-    0,                                   //  tp_as_sequence
-    &MessageMapMappingMethods,           //  tp_as_mapping
-    0,                                   //  tp_hash
-    0,                                   //  tp_call
-    0,                                   //  tp_str
-    0,                                   //  tp_getattro
-    0,                                   //  tp_setattro
-    0,                                   //  tp_as_buffer
-    Py_TPFLAGS_DEFAULT,                  //  tp_flags
-    "A map container for message",       //  tp_doc
-    0,                                   //  tp_traverse
-    0,                                   //  tp_clear
-    0,                                   //  tp_richcompare
-    0,                                   //  tp_weaklistoffset
-    MapReflectionFriend::GetIterator,    //  tp_iter
-    0,                                   //  tp_iternext
-    MessageMapMethods,                   //  tp_methods
-    0,                                   //  tp_members
-    0,                                   //  tp_getset
-    0,                                   //  tp_base
-    0,                                   //  tp_dict
-    0,                                   //  tp_descr_get
-    0,                                   //  tp_descr_set
-    0,                                   //  tp_dictoffset
-    0,                                   //  tp_init
-  };
-#endif
+PyType_Spec MessageMapContainer_Type_spec = {
+    FULL_MODULE_NAME ".MessageMapContainer", sizeof(MessageMapContainer), 0,
+    Py_TPFLAGS_DEFAULT, MessageMapContainer_Type_slots};
 
 // MapIterator /////////////////////////////////////////////////////////////////
 
@@ -1001,20 +892,18 @@
 
 bool InitMapContainers() {
   // ScalarMapContainer_Type derives from our MutableMapping type.
-  ScopedPyObjectPtr containers(PyImport_ImportModule(
-      "google.protobuf.internal.containers"));
-  if (containers == NULL) {
+  ScopedPyObjectPtr abc(PyImport_ImportModule("collections.abc"));
+  if (abc == NULL) {
     return false;
   }
 
   ScopedPyObjectPtr mutable_mapping(
-      PyObject_GetAttrString(containers.get(), "MutableMapping"));
+      PyObject_GetAttrString(abc.get(), "MutableMapping"));
   if (mutable_mapping == NULL) {
     return false;
   }
 
   Py_INCREF(mutable_mapping.get());
-#if PY_MAJOR_VERSION >= 3
   ScopedPyObjectPtr bases(PyTuple_Pack(1, mutable_mapping.get()));
   if (bases == NULL) {
     return false;
@@ -1022,35 +911,13 @@
 
   ScalarMapContainer_Type = reinterpret_cast<PyTypeObject*>(
       PyType_FromSpecWithBases(&ScalarMapContainer_Type_spec, bases.get()));
-#else
-  _ScalarMapContainer_Type.tp_base =
-      reinterpret_cast<PyTypeObject*>(mutable_mapping.get());
-
-  if (PyType_Ready(&_ScalarMapContainer_Type) < 0) {
-    return false;
-  }
-
-  ScalarMapContainer_Type = &_ScalarMapContainer_Type;
-#endif
 
   if (PyType_Ready(&MapIterator_Type) < 0) {
     return false;
   }
 
-#if PY_MAJOR_VERSION >= 3
   MessageMapContainer_Type = reinterpret_cast<PyTypeObject*>(
       PyType_FromSpecWithBases(&MessageMapContainer_Type_spec, bases.get()));
-#else
-  Py_INCREF(mutable_mapping.get());
-  _MessageMapContainer_Type.tp_base =
-      reinterpret_cast<PyTypeObject*>(mutable_mapping.get());
-
-  if (PyType_Ready(&_MessageMapContainer_Type) < 0) {
-    return false;
-  }
-
-  MessageMapContainer_Type = &_MessageMapContainer_Type;
-#endif
   return true;
 }
 
diff --git a/python/google/protobuf/pyext/message.cc b/python/google/protobuf/pyext/message.cc
index 8773417..4340afc 100644
--- a/python/google/protobuf/pyext/message.cc
+++ b/python/google/protobuf/pyext/message.cc
@@ -77,27 +77,14 @@
 #include <google/protobuf/port_def.inc>
 // clang-format on
 
-#if PY_MAJOR_VERSION >= 3
-  #define PyInt_AsLong PyLong_AsLong
-  #define PyInt_FromLong PyLong_FromLong
-  #define PyInt_FromSize_t PyLong_FromSize_t
-  #define PyString_Check PyUnicode_Check
-  #define PyString_FromString PyUnicode_FromString
-  #define PyString_FromStringAndSize PyUnicode_FromStringAndSize
-  #define PyString_FromFormat PyUnicode_FromFormat
-  #if PY_VERSION_HEX < 0x03030000
-    #error "Python 3.0 - 3.2 are not supported."
-  #else
-  #define PyString_AsString(ob) \
-    (PyUnicode_Check(ob)? PyUnicode_AsUTF8(ob): PyBytes_AsString(ob))
+#define PyString_AsString(ob) \
+  (PyUnicode_Check(ob) ? PyUnicode_AsUTF8(ob) : PyBytes_AsString(ob))
 #define PyString_AsStringAndSize(ob, charpp, sizep)                           \
   (PyUnicode_Check(ob) ? ((*(charpp) = const_cast<char*>(                     \
                                PyUnicode_AsUTF8AndSize(ob, (sizep)))) == NULL \
                               ? -1                                            \
                               : 0)                                            \
                        : PyBytes_AsStringAndSize(ob, (charpp), (sizep)))
-#endif
-#endif
 
 namespace google {
 namespace protobuf {
@@ -125,8 +112,6 @@
 
 namespace message_meta {
 
-static int InsertEmptyWeakref(PyTypeObject* base);
-
 namespace {
 // Copied over from internal 'google/protobuf/stubs/strutil.h'.
 inline void LowerString(std::string* s) {
@@ -176,8 +161,8 @@
     for (int j = 0; j < enum_descriptor->value_count(); ++j) {
       const EnumValueDescriptor* enum_value_descriptor =
           enum_descriptor->value(j);
-      ScopedPyObjectPtr value_number(PyInt_FromLong(
-          enum_value_descriptor->number()));
+      ScopedPyObjectPtr value_number(
+          PyLong_FromLong(enum_value_descriptor->number()));
       if (value_number == NULL) {
         return -1;
       }
@@ -287,13 +272,6 @@
   }
   CMessageClass* newtype = reinterpret_cast<CMessageClass*>(result.get());
 
-  // Insert the empty weakref into the base classes.
-  if (InsertEmptyWeakref(
-          reinterpret_cast<PyTypeObject*>(PythonMessage_class)) < 0 ||
-      InsertEmptyWeakref(CMessage_Type) < 0) {
-    return NULL;
-  }
-
   // Cache the descriptor, both as Python object and as C++ pointer.
   const Descriptor* descriptor =
       PyMessageDescriptor_AsDescriptor(py_descriptor);
@@ -348,32 +326,6 @@
   return PyType_Type.tp_clear(pself);
 }
 
-// This function inserts and empty weakref at the end of the list of
-// subclasses for the main protocol buffer Message class.
-//
-// This eliminates a O(n^2) behaviour in the internal add_subclass
-// routine.
-static int InsertEmptyWeakref(PyTypeObject *base_type) {
-#if PY_MAJOR_VERSION >= 3
-  // Python 3.4 has already included the fix for the issue that this
-  // hack addresses. For further background and the fix please see
-  // https://bugs.python.org/issue17936.
-  return 0;
-#else
-#ifdef Py_DEBUG
-  // The code below causes all new subclasses to append an entry, which is never
-  // cleared. This is a small memory leak, which we disable in Py_DEBUG mode
-  // to have stable refcounting checks.
-#else
-  PyObject *subclasses = base_type->tp_subclasses;
-  if (subclasses && PyList_CheckExact(subclasses)) {
-    return PyList_Append(subclasses, kEmptyWeakref);
-  }
-#endif  // !Py_DEBUG
-  return 0;
-#endif  // PY_MAJOR_VERSION >= 3
-}
-
 // The _extensions_by_name dictionary is built on every access.
 // TODO(amauryfa): Migrate all users to pool.FindAllExtensions()
 static PyObject* GetExtensionsByName(CMessageClass *self, void *closure) {
@@ -426,7 +378,7 @@
     if (extension == NULL) {
       return NULL;
     }
-    ScopedPyObjectPtr number(PyInt_FromLong(extensions[i]->number()));
+    ScopedPyObjectPtr number(PyLong_FromLong(extensions[i]->number()));
     if (number == NULL) {
       return NULL;
     }
@@ -464,7 +416,7 @@
           self->message_descriptor->FindExtensionByLowercaseName(field_name);
     }
     if (field) {
-      return PyInt_FromLong(field->number());
+      return PyLong_FromLong(field->number());
     }
   }
   PyErr_SetObject(PyExc_AttributeError, name);
@@ -617,20 +569,6 @@
 
 template <class T>
 bool CheckAndGetInteger(PyObject* arg, T* value) {
-  // The fast path.
-#if PY_MAJOR_VERSION < 3
-  // For the typical case, offer a fast path.
-  if (PROTOBUF_PREDICT_TRUE(PyInt_Check(arg))) {
-    long int_result = PyInt_AsLong(arg);
-    if (PROTOBUF_PREDICT_TRUE(IsValidNumericCast<T>(int_result))) {
-      *value = static_cast<T>(int_result);
-      return true;
-    } else {
-      OutOfRangeError(arg);
-      return false;
-    }
-  }
-#endif
   // This effectively defines an integer as "an object that can be cast as
   // an integer and can be used as an ordinal number".
   // This definition includes everything that implements numbers.Integral
@@ -720,7 +658,7 @@
 }
 
 bool CheckAndGetBool(PyObject* arg, bool* value) {
-  long long_value = PyInt_AsLong(arg);
+  long long_value = PyLong_AsLong(arg);  // NOLINT
   if (long_value == -1 && PyErr_Occurred()) {
     FormatTypeError(arg, "int, long, bool");
     return false;
@@ -977,7 +915,7 @@
 // descriptor, otherwise simply return value.  Always returns a new reference.
 static PyObject* GetIntegerEnumValue(const FieldDescriptor& descriptor,
                                      PyObject* value) {
-  if (PyString_Check(value) || PyUnicode_Check(value)) {
+  if (PyUnicode_Check(value)) {
     const EnumDescriptor* enum_descriptor = descriptor.enum_type();
     if (enum_descriptor == NULL) {
       PyErr_SetString(PyExc_TypeError, "not an enum field");
@@ -994,7 +932,7 @@
       PyErr_Format(PyExc_ValueError, "unknown enum label \"%s\"", enum_label);
       return NULL;
     }
-    return PyInt_FromLong(enum_value_descriptor->number());
+    return PyLong_FromLong(enum_value_descriptor->number());
   }
   Py_INCREF(value);
   return value;
@@ -1016,15 +954,7 @@
 
   if (PySlice_Check(slice)) {
     from = to = step = slice_length = 0;
-#if PY_MAJOR_VERSION < 3
-    PySlice_GetIndicesEx(
-        reinterpret_cast<PySliceObject*>(slice),
-        length, &from, &to, &step, &slice_length);
-#else
-    PySlice_GetIndicesEx(
-        slice,
-        length, &from, &to, &step, &slice_length);
-#endif
+    PySlice_GetIndicesEx(slice, length, &from, &to, &step, &slice_length);
     if (from < to) {
       min = from;
       max = to - 1;
@@ -1121,7 +1051,7 @@
   PyObject* name;
   PyObject* value;
   while (PyDict_Next(kwargs, &pos, &name, &value)) {
-    if (!(PyString_Check(name) || PyUnicode_Check(name))) {
+    if (!(PyUnicode_Check(name))) {
       PyErr_SetString(PyExc_ValueError, "Field name must be a string");
       return -1;
     }
@@ -1396,7 +1326,7 @@
     if (initialization_errors == NULL) {
       return NULL;
     }
-    ScopedPyObjectPtr extend_name(PyString_FromString("extend"));
+    ScopedPyObjectPtr extend_name(PyUnicode_FromString("extend"));
     if (extend_name == NULL) {
       return NULL;
     }
@@ -1469,16 +1399,10 @@
 PyObject* HasField(CMessage* self, PyObject* arg) {
   char* field_name;
   Py_ssize_t size;
-#if PY_MAJOR_VERSION < 3
-  if (PyString_AsStringAndSize(arg, &field_name, &size) < 0) {
-    return NULL;
-  }
-#else
   field_name = const_cast<char*>(PyUnicode_AsUTF8AndSize(arg, &size));
   if (!field_name) {
     return NULL;
   }
-#endif
 
   Message* message = self->message;
   bool is_in_oneof;
@@ -1746,7 +1670,7 @@
     if (errors == NULL) {
       return NULL;
     }
-    ScopedPyObjectPtr comma(PyString_FromString(","));
+    ScopedPyObjectPtr comma(PyUnicode_FromString(","));
     if (comma == NULL) {
       return NULL;
     }
@@ -1872,7 +1796,7 @@
     PyErr_SetString(PyExc_ValueError, "Unable to convert message to str");
     return NULL;
   }
-  return PyString_FromString(output.c_str());
+  return PyUnicode_FromString(output.c_str());
 }
 
 PyObject* MergeFrom(CMessage* self, PyObject* arg) {
@@ -2004,9 +1928,9 @@
     // TODO(jieluo): Raise error and return NULL instead.
     // b/27494216
     PyErr_Warn(nullptr, "Unexpected end-group tag: Not all data was converted");
-    return PyInt_FromLong(data.len - ctx.BytesUntilLimit(ptr));
+    return PyLong_FromLong(data.len - ctx.BytesUntilLimit(ptr));
   }
-  return PyInt_FromLong(data.len);
+  return PyLong_FromLong(data.len);
 }
 
 static PyObject* ParseFromString(CMessage* self, PyObject* arg) {
@@ -2071,7 +1995,7 @@
     Py_RETURN_NONE;
   } else {
     const std::string& name = field_in_oneof->name();
-    return PyString_FromStringAndSize(name.c_str(), name.size());
+    return PyUnicode_FromStringAndSize(name.c_str(), name.size());
   }
 }
 
@@ -2171,8 +2095,8 @@
   }
   for (size_t i = 0; i < errors.size(); ++i) {
     const std::string& error = errors[i];
-    PyObject* error_string = PyString_FromStringAndSize(
-        error.c_str(), error.length());
+    PyObject* error_string =
+        PyUnicode_FromStringAndSize(error.c_str(), error.length());
     if (error_string == NULL) {
       Py_DECREF(error_list);
       return NULL;
@@ -2228,7 +2152,7 @@
   switch (field_descriptor->cpp_type()) {
     case FieldDescriptor::CPPTYPE_INT32: {
       int32_t value = reflection->GetInt32(*message, field_descriptor);
-      result = PyInt_FromLong(value);
+      result = PyLong_FromLong(value);
       break;
     }
     case FieldDescriptor::CPPTYPE_INT64: {
@@ -2238,7 +2162,7 @@
     }
     case FieldDescriptor::CPPTYPE_UINT32: {
       uint32_t value = reflection->GetUInt32(*message, field_descriptor);
-      result = PyInt_FromSize_t(value);
+      result = PyLong_FromSsize_t(value);
       break;
     }
     case FieldDescriptor::CPPTYPE_UINT64: {
@@ -2271,7 +2195,7 @@
     case FieldDescriptor::CPPTYPE_ENUM: {
       const EnumValueDescriptor* enum_value =
           message->GetReflection()->GetEnum(*message, field_descriptor);
-      result = PyInt_FromLong(enum_value->number());
+      result = PyLong_FromLong(enum_value->number());
       break;
     }
     default:
@@ -2461,7 +2385,7 @@
   if (text_format == NULL) {
     return NULL;
   }
-  ScopedPyObjectPtr method_name(PyString_FromString("MessageToString"));
+  ScopedPyObjectPtr method_name(PyUnicode_FromString("MessageToString"));
   if (method_name == NULL) {
     return NULL;
   }
@@ -2472,11 +2396,7 @@
   if (encoded == NULL) {
     return NULL;
   }
-#if PY_MAJOR_VERSION < 3
-  PyObject* decoded = PyString_AsDecodedObject(encoded.get(), "utf-8", NULL);
-#else
   PyObject* decoded = PyUnicode_FromEncodedObject(encoded.get(), "utf-8", NULL);
-#endif
   if (decoded == NULL) {
     return NULL;
   }
@@ -2966,7 +2886,7 @@
   // TODO(gps): Check all return values in this function for NULL and propagate
   // the error (MemoryError) on up to result in an import failure.  These should
   // also be freed and reset to NULL during finalization.
-  kDESCRIPTOR = PyString_FromString("DESCRIPTOR");
+  kDESCRIPTOR = PyUnicode_FromString("DESCRIPTOR");
 
   PyObject *dummy_obj = PySet_New(NULL);
   kEmptyWeakref = PyWeakref_NewRef(dummy_obj, NULL);
@@ -3035,11 +2955,7 @@
         reinterpret_cast<PyObject*>(&RepeatedCompositeContainer_Type));
 
     // Register them as MutableSequence.
-#if PY_MAJOR_VERSION >= 3
     ScopedPyObjectPtr collections(PyImport_ImportModule("collections.abc"));
-#else
-    ScopedPyObjectPtr collections(PyImport_ImportModule("collections"));
-#endif
     if (collections == NULL) {
       return false;
     }
diff --git a/python/google/protobuf/pyext/message_factory.cc b/python/google/protobuf/pyext/message_factory.cc
index 7905be0..30dfab8 100644
--- a/python/google/protobuf/pyext/message_factory.cc
+++ b/python/google/protobuf/pyext/message_factory.cc
@@ -38,17 +38,12 @@
 #include <google/protobuf/pyext/message_factory.h>
 #include <google/protobuf/pyext/scoped_pyobject_ptr.h>
 
-#if PY_MAJOR_VERSION >= 3
-  #if PY_VERSION_HEX < 0x03030000
-    #error "Python 3.0 - 3.2 are not supported."
-  #endif
-  #define PyString_AsStringAndSize(ob, charpp, sizep) \
-    (PyUnicode_Check(ob) ? ((*(charpp) = const_cast<char*>(                   \
+#define PyString_AsStringAndSize(ob, charpp, sizep)                           \
+  (PyUnicode_Check(ob) ? ((*(charpp) = const_cast<char*>(                     \
                                PyUnicode_AsUTF8AndSize(ob, (sizep)))) == NULL \
                               ? -1                                            \
                               : 0)                                            \
-                        : PyBytes_AsStringAndSize(ob, (charpp), (sizep)))
-#endif
+                       : PyBytes_AsStringAndSize(ob, (charpp), (sizep)))
 
 namespace google {
 namespace protobuf {
diff --git a/python/google/protobuf/pyext/message_module.cc b/python/google/protobuf/pyext/message_module.cc
index 4125dd7..971d2ba 100644
--- a/python/google/protobuf/pyext/message_module.cc
+++ b/python/google/protobuf/pyext/message_module.cc
@@ -95,7 +95,6 @@
     // DO NOT USE: For migration and testing only.
     {NULL, NULL}};
 
-#if PY_MAJOR_VERSION >= 3
 static struct PyModuleDef _module = {PyModuleDef_HEAD_INIT,
                                      "_message",
                                      module_docstring,
@@ -105,27 +104,17 @@
                                      NULL,
                                      NULL,
                                      NULL};
-#define INITFUNC PyInit__message
-#define INITFUNC_ERRORVAL NULL
-#else  // Python 2
-#define INITFUNC init_message
-#define INITFUNC_ERRORVAL
-#endif
 
-PyMODINIT_FUNC INITFUNC() {
+PyMODINIT_FUNC PyInit__message() {
   PyObject* m;
-#if PY_MAJOR_VERSION >= 3
   m = PyModule_Create(&_module);
-#else
-  m = Py_InitModule3("_message", ModuleMethods, module_docstring);
-#endif
   if (m == NULL) {
-    return INITFUNC_ERRORVAL;
+    return NULL;
   }
 
   if (!google::protobuf::python::InitProto2MessageModule(m)) {
     Py_DECREF(m);
-    return INITFUNC_ERRORVAL;
+    return NULL;
   }
 
   // Adds the C++ API
@@ -137,10 +126,8 @@
           })) {
     PyModule_AddObject(m, "proto_API", api);
   } else {
-    return INITFUNC_ERRORVAL;
+    return NULL;
   }
 
-#if PY_MAJOR_VERSION >= 3
   return m;
-#endif
 }
diff --git a/python/google/protobuf/pyext/repeated_composite_container.cc b/python/google/protobuf/pyext/repeated_composite_container.cc
index f3d6fc3..2e8ff4b 100644
--- a/python/google/protobuf/pyext/repeated_composite_container.cc
+++ b/python/google/protobuf/pyext/repeated_composite_container.cc
@@ -48,12 +48,6 @@
 #include <google/protobuf/reflection.h>
 #include <google/protobuf/stubs/map_util.h>
 
-#if PY_MAJOR_VERSION >= 3
-  #define PyInt_Check PyLong_Check
-  #define PyInt_AsLong PyLong_AsLong
-  #define PyInt_FromLong PyLong_FromLong
-#endif
-
 namespace google {
 namespace protobuf {
 namespace python {
@@ -246,13 +240,8 @@
     Py_ssize_t from, to, step, slicelength, cur, i;
     PyObject* result;
 
-#if PY_MAJOR_VERSION >= 3
-    if (PySlice_GetIndicesEx(item,
-                             length, &from, &to, &step, &slicelength) == -1) {
-#else
-    if (PySlice_GetIndicesEx(reinterpret_cast<PySliceObject*>(item),
-                             length, &from, &to, &step, &slicelength) == -1) {
-#endif
+    if (PySlice_GetIndicesEx(item, length, &from, &to, &step, &slicelength) ==
+        -1) {
       return nullptr;
     }
 
diff --git a/python/google/protobuf/pyext/repeated_scalar_container.cc b/python/google/protobuf/pyext/repeated_scalar_container.cc
index d76114b..4b6d12a 100644
--- a/python/google/protobuf/pyext/repeated_scalar_container.cc
+++ b/python/google/protobuf/pyext/repeated_scalar_container.cc
@@ -46,15 +46,8 @@
 #include <google/protobuf/pyext/message.h>
 #include <google/protobuf/pyext/scoped_pyobject_ptr.h>
 
-#if PY_MAJOR_VERSION >= 3
-#define PyInt_FromLong PyLong_FromLong
-#if PY_VERSION_HEX < 0x03030000
-#error "Python 3.0 - 3.2 are not supported."
-#else
 #define PyString_AsString(ob) \
   (PyUnicode_Check(ob) ? PyUnicode_AsUTF8(ob) : PyBytes_AsString(ob))
-#endif
-#endif
 
 namespace google {
 namespace protobuf {
@@ -210,7 +203,7 @@
     case FieldDescriptor::CPPTYPE_INT32: {
       int32_t value =
           reflection->GetRepeatedInt32(*message, field_descriptor, index);
-      result = PyInt_FromLong(value);
+      result = PyLong_FromLong(value);
       break;
     }
     case FieldDescriptor::CPPTYPE_INT64: {
@@ -253,7 +246,7 @@
       const EnumValueDescriptor* enum_value =
           message->GetReflection()->GetRepeatedEnum(*message, field_descriptor,
                                                     index);
-      result = PyInt_FromLong(enum_value->number());
+      result = PyLong_FromLong(enum_value->number());
       break;
     }
     case FieldDescriptor::CPPTYPE_STRING: {
@@ -279,22 +272,12 @@
   Py_ssize_t length;
   Py_ssize_t slicelength;
   bool return_list = false;
-#if PY_MAJOR_VERSION < 3
-  if (PyInt_Check(slice)) {
-    from = to = PyInt_AsLong(slice);
-  } else  // NOLINT
-#endif
-      if (PyLong_Check(slice)) {
+  if (PyLong_Check(slice)) {
     from = to = PyLong_AsLong(slice);
   } else if (PySlice_Check(slice)) {
     length = Len(pself);
-#if PY_MAJOR_VERSION >= 3
     if (PySlice_GetIndicesEx(slice, length, &from, &to, &step, &slicelength) ==
         -1) {
-#else
-    if (PySlice_GetIndicesEx(reinterpret_cast<PySliceObject*>(slice), length,
-                             &from, &to, &step, &slicelength) == -1) {
-#endif
       return nullptr;
     }
     return_list = true;
@@ -436,23 +419,13 @@
   Message* message = self->parent->message;
   const FieldDescriptor* field_descriptor = self->parent_field_descriptor;
 
-#if PY_MAJOR_VERSION < 3
-  if (PyInt_Check(slice)) {
-    from = to = PyInt_AsLong(slice);
-  } else  // NOLINT
-#endif
-      if (PyLong_Check(slice)) {
+  if (PyLong_Check(slice)) {
     from = to = PyLong_AsLong(slice);
   } else if (PySlice_Check(slice)) {
     const Reflection* reflection = message->GetReflection();
     length = reflection->FieldSize(*message, field_descriptor);
-#if PY_MAJOR_VERSION >= 3
     if (PySlice_GetIndicesEx(slice, length, &from, &to, &step, &slicelength) ==
         -1) {
-#else
-    if (PySlice_GetIndicesEx(reinterpret_cast<PySliceObject*>(slice), length,
-                             &from, &to, &step, &slicelength) == -1) {
-#endif
       return -1;
     }
     create_list = true;
diff --git a/python/google/protobuf/pyext/unknown_fields.cc b/python/google/protobuf/pyext/unknown_fields.cc
index deb86e6..7f4fb23 100644
--- a/python/google/protobuf/pyext/unknown_fields.cc
+++ b/python/google/protobuf/pyext/unknown_fields.cc
@@ -40,10 +40,6 @@
 #include <google/protobuf/unknown_field_set.h>
 #include <google/protobuf/wire_format_lite.h>
 
-#if PY_MAJOR_VERSION >= 3
-  #define PyInt_FromLong PyLong_FromLong
-#endif
-
 namespace google {
 namespace protobuf {
 namespace python {
@@ -237,7 +233,7 @@
   if (unknown_field == NULL) {
     return NULL;
   }
-  return PyInt_FromLong(unknown_field->number());
+  return PyLong_FromLong(unknown_field->number());
 }
 
 using internal::WireFormatLite;
@@ -267,7 +263,7 @@
       wire_type = WireFormatLite::WIRETYPE_START_GROUP;
       break;
   }
-  return PyInt_FromLong(wire_type);
+  return PyLong_FromLong(wire_type);
 }
 
 static PyObject* GetData(PyUnknownFieldRef* self, void *closure) {
@@ -278,13 +274,13 @@
   PyObject* data = NULL;
   switch (field->type()) {
     case UnknownField::TYPE_VARINT:
-      data = PyInt_FromLong(field->varint());
+      data = PyLong_FromLong(field->varint());
       break;
     case UnknownField::TYPE_FIXED32:
-      data = PyInt_FromLong(field->fixed32());
+      data = PyLong_FromLong(field->fixed32());
       break;
     case UnknownField::TYPE_FIXED64:
-      data = PyInt_FromLong(field->fixed64());
+      data = PyLong_FromLong(field->fixed64());
       break;
     case UnknownField::TYPE_LENGTH_DELIMITED:
       data = PyBytes_FromStringAndSize(field->length_delimited().data(),
diff --git a/python/release.sh b/python/release.sh
index 8ec6e11..15a70db 100755
--- a/python/release.sh
+++ b/python/release.sh
@@ -73,6 +73,9 @@
   sed -i -r "s/__version__ = '.*'/__version__ = '${VERSION}.${DEV}'/" python/google/protobuf/__init__.py
 fi
 
+# Copy LICENSE
+cp LICENSE python/LICENSE
+
 cd python
 
 # Run tests locally.
diff --git a/python/setup.py b/python/setup.py
index 33d7420..63118c2 100755
--- a/python/setup.py
+++ b/python/setup.py
@@ -157,6 +157,7 @@
     return [(pkg, mod, fil) for (pkg, mod, fil) in modules
             if not any(fnmatch.fnmatchcase(fil, pat=pat) for pat in exclude)]
 
+
 class build_ext(_build_ext):
 
   def get_ext_filename(self, ext_name):
@@ -308,4 +309,5 @@
       },
       install_requires=install_requires,
       ext_modules=ext_module_list,
+      python_requires='>=3.5',
   )
diff --git a/ruby/Rakefile b/ruby/Rakefile
index 60ec6ea..8aae2ee 100644
--- a/ruby/Rakefile
+++ b/ruby/Rakefile
@@ -61,22 +61,24 @@
     output_file = proto_file.sub(/\.proto$/, "_pb.rb")
     genproto_output << output_file
     file output_file => proto_file do |file_task|
-      sh "#{protoc_command} -I../src -I. --ruby_out=. #{proto_file}"
+      sh "#{protoc_command} -I../src -I. -I./tests --ruby_out=.  #{proto_file}"
     end
   end
 end
 
 if RUBY_PLATFORM == "java"
-  if `which mvn` == ''
-    raise ArgumentError, "maven needs to be installed"
-  end
-  task :clean do
+  task :clean => :require_mvn do
     system("mvn --batch-mode clean")
   end
 
-  task :compile do
+  task :compile => :require_mvn do
     system("mvn --batch-mode package")
   end
+
+  task :require_mvn do
+    raise ArgumentError, "maven needs to be installed" if `which mvn` == ''
+  end
+
 else
   Rake::ExtensionTask.new("protobuf_c", spec) do |ext|
     unless RUBY_PLATFORM =~ /darwin/
@@ -95,7 +97,22 @@
     ]
   end
 
+  task 'gem:java' do
+    sh "rm Gemfile.lock"
+    require 'rake_compiler_dock'
+    # Specify the repo root as the working and mount directory to provide access
+    # to the java directory
+    repo_root = File.realdirpath File.join(Dir.pwd, '..')
+    RakeCompilerDock.sh <<-"EOT", platform: 'jruby', rubyvm: :jruby, mountdir: repo_root, workdir: repo_root
+      sudo apt-get install maven -y && \
+      cd java && mvn install -Dmaven.test.skip=true && cd ../ruby && \
+      bundle && \
+      IN_DOCKER=true rake compile gem
+    EOT
+  end
+
   task 'gem:windows' do
+    sh "rm Gemfile.lock"
     require 'rake_compiler_dock'
     ['x86-mingw32', 'x64-mingw32', 'x86_64-linux', 'x86-linux'].each do |plat|
       RakeCompilerDock.sh <<-"EOT", platform: plat
@@ -111,7 +128,7 @@
       system "rake cross native gem RUBY_CC_VERSION=3.0.0:2.7.0:2.6.0:2.5.1:2.4.0:2.3.0"
     end
   else
-    task 'gem:native' => [:genproto, 'gem:windows']
+    task 'gem:native' => [:genproto, 'gem:windows', 'gem:java']
   end
 end
 
diff --git a/ruby/compatibility_tests/v3.0.0/test.sh b/ruby/compatibility_tests/v3.0.0/test.sh
index d5a8fd7..1a9b798 100755
--- a/ruby/compatibility_tests/v3.0.0/test.sh
+++ b/ruby/compatibility_tests/v3.0.0/test.sh
@@ -14,4 +14,4 @@
 chmod +x protoc
 
 # Run tests
-rake test
+RUBYLIB=../../lib:. rake test
diff --git a/ruby/ext/google/protobuf_c/repeated_field.c b/ruby/ext/google/protobuf_c/repeated_field.c
index 88e8434..5ff3c76 100644
--- a/ruby/ext/google/protobuf_c/repeated_field.c
+++ b/ruby/ext/google/protobuf_c/repeated_field.c
@@ -551,6 +551,7 @@
     RepeatedField* dupped = ruby_to_RepeatedField(dupped_);
     upb_array *dupped_array = RepeatedField_GetMutable(dupped_);
     upb_arena* arena = Arena_get(dupped->arena);
+    Arena_fuse(list_rptfield->arena, arena);
     int size = upb_array_size(list_rptfield->array);
     int i;
 
diff --git a/ruby/google-protobuf.gemspec b/ruby/google-protobuf.gemspec
index 36d325e..3647d8b 100644
--- a/ruby/google-protobuf.gemspec
+++ b/ruby/google-protobuf.gemspec
@@ -1,6 +1,6 @@
 Gem::Specification.new do |s|
   s.name        = "google-protobuf"
-  s.version     = "3.17.3"
+  s.version     = "3.18.0"
   git_tag       = "v#{s.version.to_s.sub('.rc.', '-rc')}" # Converts X.Y.Z.rc.N to vX.Y.Z-rcN, used for the git tag
   s.licenses    = ["BSD-3-Clause"]
   s.summary     = "Protocol Buffers"
diff --git a/ruby/lib/google/protobuf.rb b/ruby/lib/google/protobuf.rb
index 9368768..f939a4c 100644
--- a/ruby/lib/google/protobuf.rb
+++ b/ruby/lib/google/protobuf.rb
@@ -51,9 +51,9 @@
     require 'google/protobuf_c'
   end
 
-  require 'google/protobuf/descriptor_dsl'
 end
 
+require 'google/protobuf/descriptor_dsl'
 require 'google/protobuf/repeated_field'
 
 module Google
diff --git a/ruby/lib/google/protobuf/descriptor_dsl.rb b/ruby/lib/google/protobuf/descriptor_dsl.rb
index ba1a255..c3e9a5a 100644
--- a/ruby/lib/google/protobuf/descriptor_dsl.rb
+++ b/ruby/lib/google/protobuf/descriptor_dsl.rb
@@ -301,8 +301,8 @@
           internal_add_field(:LABEL_REQUIRED, name, type, number, type_class, options)
         end
 
-        def repeated(name, type, number, type_class = nil)
-          internal_add_field(:LABEL_REPEATED, name, type, number, type_class, nil)
+        def repeated(name, type, number, type_class = nil, options=nil)
+          internal_add_field(:LABEL_REPEATED, name, type, number, type_class, options)
         end
 
         def oneof(name, &block)
diff --git a/ruby/pom.xml b/ruby/pom.xml
index 6c96bf4..b951845 100644
--- a/ruby/pom.xml
+++ b/ruby/pom.xml
@@ -1,7 +1,5 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<project xmlns="http://maven.apache.org/POM/4.0.0"
-         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
     <modelVersion>4.0.0</modelVersion>
     <parent>
       <groupId>com.google</groupId>
@@ -11,7 +9,7 @@
 
     <groupId>com.google.protobuf.jruby</groupId>
     <artifactId>protobuf-jruby</artifactId>
-    <version>1.0-SNAPSHOT</version>
+    <version>3.18.0</version>
     <name>Protocol Buffer JRuby native extension</name>
     <description>
       Protocol Buffers are a way of encoding structured data in an efficient yet
@@ -74,6 +72,12 @@
         </plugins>
     </build>
     <dependencies>
+        <!-- Ordering of dependencies matters to update_version.py -->
+        <dependency>
+          <groupId>com.google.protobuf</groupId>
+          <artifactId>protobuf-java-util</artifactId>
+          <version>3.18.0</version>
+        </dependency>
         <dependency>
             <groupId>com.fasterxml.jackson.core</groupId>
             <artifactId>jackson-core</artifactId>
@@ -85,10 +89,5 @@
             <version>9.2.11.1</version>
             <scope>provided</scope>
         </dependency>
-        <dependency>
-            <groupId>com.google.protobuf</groupId>
-            <artifactId>protobuf-java-util</artifactId>
-            <version>3.13.0</version>
-        </dependency>
     </dependencies>
 </project>
diff --git a/ruby/src/main/java/com/google/protobuf/jruby/RubyBuilder.java b/ruby/src/main/java/com/google/protobuf/jruby/RubyBuilder.java
deleted file mode 100644
index b19ea64..0000000
--- a/ruby/src/main/java/com/google/protobuf/jruby/RubyBuilder.java
+++ /dev/null
@@ -1,147 +0,0 @@
-/*
- * Protocol Buffers - Google's data interchange format
- * Copyright 2014 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.
- */
-
-package com.google.protobuf.jruby;
-
-import org.jruby.*;
-import org.jruby.anno.JRubyClass;
-import org.jruby.anno.JRubyMethod;
-import org.jruby.runtime.*;
-import org.jruby.runtime.builtin.IRubyObject;
-
-@JRubyClass(name = "Builder")
-public class RubyBuilder extends RubyObject {
-    public static void createRubyBuilder(Ruby runtime) {
-        RubyModule internal = runtime.getClassFromPath("Google::Protobuf::Internal");
-        RubyClass cBuilder = internal.defineClassUnder("Builder", runtime.getObject(), new ObjectAllocator() {
-            @Override
-            public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
-                return new RubyBuilder(runtime, klazz);
-            }
-        });
-        cBuilder.defineAnnotatedMethods(RubyBuilder.class);
-    }
-
-    public RubyBuilder(Ruby runtime, RubyClass metaClass) {
-        super(runtime, metaClass);
-        this.cFileBuilderContext = (RubyClass) runtime.getClassFromPath("Google::Protobuf::Internal::FileBuilderContext");
-    }
-
-    /*
-     * call-seq:
-     *     Builder.new => builder
-     *
-     * Creates a new Builder. A Builder can accumulate a set of new message and enum
-     * descriptors and atomically register them into a pool in a way that allows for
-     * (co)recursive type references.
-     */
-    @JRubyMethod
-    public IRubyObject initialize(ThreadContext context, IRubyObject descriptorPool) {
-        this.descriptorPool = (RubyDescriptorPool) descriptorPool;
-        return this;
-    }
-
-    /*
-     * call-seq:
-     *     Builder.add_message(name, &block)
-     *
-     * Old and deprecated way to create a new descriptor.
-     * See FileBuilderContext.add_message for the recommended way.
-     *
-     * Exists for backwards compatibility to allow building descriptor pool for
-     * files generated by protoc which don't add messages within "add_file" block.
-     * Descriptors created this way get assigned to a default empty FileDescriptor.
-     */
-    @JRubyMethod(name = "add_message")
-    public IRubyObject addMessage(ThreadContext context, IRubyObject name, Block block) {
-        ensureDefaultFileBuilder(context);
-        defaultFileBuilder.addMessage(context, name, block);
-        return context.nil;
-    }
-
-    /*
-     * call-seq:
-     *     Builder.add_enum(name, &block)
-     *
-     * Old and deprecated way to create a new enum descriptor.
-     * See FileBuilderContext.add_enum for the recommended way.
-     *
-     * Exists for backwards compatibility to allow building descriptor pool for
-     * files generated by protoc which don't add enums within "add_file" block.
-     * Enum descriptors created this way get assigned to a default empty
-     * FileDescriptor.
-     */
-    @JRubyMethod(name = "add_enum")
-    public IRubyObject addEnum(ThreadContext context, IRubyObject name, Block block) {
-        ensureDefaultFileBuilder(context);
-        defaultFileBuilder.addEnum(context, name, block);
-        return context.nil;
-    }
-
-    /*
-     * call-seq:
-     *     Builder.add_file(name, options = nil, &block)
-     *
-     * Creates a new, file descriptor with the given name and options and invokes
-     * the block in the context of a FileBuilderContext on that descriptor. The
-     * block can then call FileBuilderContext#add_message or
-     * FileBuilderContext#add_enum to define new messages or enums, respectively.
-     *
-     * This is the recommended, idiomatic way to build file descriptors.
-     */
-    @JRubyMethod(name = "add_file")
-    public IRubyObject addFile(ThreadContext context, IRubyObject name, IRubyObject options, Block block) {
-        RubyFileBuilderContext ctx = (RubyFileBuilderContext) cFileBuilderContext.newInstance(context, descriptorPool, name, options, Block.NULL_BLOCK);
-        ctx.instance_eval(context, block);
-        ctx.build(context);
-        return context.nil;
-    }
-
-    /*
-     * Used to trigger the build when using the deprecated syntax
-     */
-    protected void build(ThreadContext context) {
-        if (defaultFileBuilder != null) {
-            defaultFileBuilder.build(context);
-        }
-    }
-
-    private void ensureDefaultFileBuilder(ThreadContext context) {
-        if (defaultFileBuilder == null) {
-            this.defaultFileBuilder = (RubyFileBuilderContext) cFileBuilderContext.newInstance(context, descriptorPool, context.runtime.newString("ruby_default_file.proto"), Block.NULL_BLOCK);
-        }
-    }
-
-    private RubyClass cFileBuilderContext;
-    private RubyDescriptorPool descriptorPool;
-    private RubyFileBuilderContext defaultFileBuilder;
-}
diff --git a/ruby/src/main/java/com/google/protobuf/jruby/RubyDescriptorPool.java b/ruby/src/main/java/com/google/protobuf/jruby/RubyDescriptorPool.java
index 99a7f02..6cdb341 100644
--- a/ruby/src/main/java/com/google/protobuf/jruby/RubyDescriptorPool.java
+++ b/ruby/src/main/java/com/google/protobuf/jruby/RubyDescriptorPool.java
@@ -37,9 +37,11 @@
 import com.google.protobuf.Descriptors.DescriptorValidationException;
 import com.google.protobuf.Descriptors.EnumDescriptor;
 import com.google.protobuf.Descriptors.FileDescriptor;
+import com.google.protobuf.InvalidProtocolBufferException;
 import org.jruby.*;
 import org.jruby.anno.JRubyClass;
 import org.jruby.anno.JRubyMethod;
+import org.jruby.exceptions.RaiseException;
 import org.jruby.runtime.*;
 import org.jruby.runtime.builtin.IRubyObject;
 
@@ -61,7 +63,6 @@
 
         cDescriptorPool.defineAnnotatedMethods(RubyDescriptorPool.class);
         descriptorPool = (RubyDescriptorPool) cDescriptorPool.newInstance(runtime.getCurrentContext(), Block.NULL_BLOCK);
-        cBuilder = (RubyClass) runtime.getClassFromPath("Google::Protobuf::Internal::Builder");
         cDescriptor = (RubyClass) runtime.getClassFromPath("Google::Protobuf::Descriptor");
         cEnumDescriptor = (RubyClass) runtime.getClassFromPath("Google::Protobuf::EnumDescriptor");
     }
@@ -74,9 +75,10 @@
 
     @JRubyMethod
     public IRubyObject build(ThreadContext context, Block block) {
-        RubyBuilder ctx = (RubyBuilder) cBuilder.newInstance(context, this, Block.NULL_BLOCK);
+        RubyClass cBuilder = (RubyClass) context.runtime.getClassFromPath("Google::Protobuf::Internal::Builder");
+        RubyBasicObject ctx = (RubyBasicObject) cBuilder.newInstance(context, this, Block.NULL_BLOCK);
         ctx.instance_eval(context, block);
-        ctx.build(context); // Needs to be called to support the deprecated syntax
+        ctx.callMethod(context, "build"); // Needs to be called to support the deprecated syntax
         return context.nil;
     }
 
@@ -109,6 +111,18 @@
         return descriptorPool;
     }
 
+    @JRubyMethod(required = 1)
+    public IRubyObject add_serialized_file (ThreadContext context, IRubyObject data ) {
+        byte[] bin = data.convertToString().getBytes();
+        try {
+            FileDescriptorProto.Builder builder = FileDescriptorProto.newBuilder().mergeFrom(bin);
+            registerFileDescriptor(context, builder);
+        } catch (InvalidProtocolBufferException e) {
+            throw RaiseException.from(context.runtime, (RubyClass) context.runtime.getClassFromPath("Google::Protobuf::ParseError"), e.getMessage());
+        }
+        return context.nil;
+    }
+
     protected void registerFileDescriptor(ThreadContext context, FileDescriptorProto.Builder builder) {
         final FileDescriptor fd;
         try {
@@ -157,7 +171,6 @@
         return fileDescriptors.toArray(new FileDescriptor[fileDescriptors.size()]);
     }
 
-    private static RubyClass cBuilder;
     private static RubyClass cDescriptor;
     private static RubyClass cEnumDescriptor;
     private static RubyDescriptorPool descriptorPool;
diff --git a/ruby/src/main/java/com/google/protobuf/jruby/RubyEnumBuilderContext.java b/ruby/src/main/java/com/google/protobuf/jruby/RubyEnumBuilderContext.java
deleted file mode 100644
index 38d31ad..0000000
--- a/ruby/src/main/java/com/google/protobuf/jruby/RubyEnumBuilderContext.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Protocol Buffers - Google's data interchange format
- * Copyright 2014 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.
- */
-
-package com.google.protobuf.jruby;
-
-import com.google.protobuf.DescriptorProtos.EnumDescriptorProto;
-import org.jruby.Ruby;
-import org.jruby.RubyClass;
-import org.jruby.RubyModule;
-import org.jruby.RubyNumeric;
-import org.jruby.RubyObject;
-import org.jruby.anno.JRubyClass;
-import org.jruby.anno.JRubyMethod;
-import org.jruby.runtime.ObjectAllocator;
-import org.jruby.runtime.ThreadContext;
-import org.jruby.runtime.builtin.IRubyObject;
-
-@JRubyClass(name = "EnumBuilderContext")
-public class RubyEnumBuilderContext extends RubyObject {
-    public static void createRubyEnumBuilderContext(Ruby runtime) {
-        RubyModule internal = runtime.getClassFromPath("Google::Protobuf::Internal");
-        RubyClass cEnumBuilderContext = internal.defineClassUnder("EnumBuilderContext", runtime.getObject(), new ObjectAllocator() {
-            @Override
-            public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
-                return new RubyEnumBuilderContext(runtime, klazz);
-            }
-        });
-        cEnumBuilderContext.defineAnnotatedMethods(RubyEnumBuilderContext.class);
-    }
-
-    public RubyEnumBuilderContext(Ruby ruby, RubyClass klazz) {
-        super(ruby, klazz);
-    }
-
-    @JRubyMethod
-    public IRubyObject initialize(ThreadContext context, IRubyObject fileBuilderContext, IRubyObject name) {
-        this.fileBuilderContext = (RubyFileBuilderContext) fileBuilderContext;
-        this.builder = this.fileBuilderContext.getNewEnumBuilder();
-        this.builder.setName(name.asJavaString());
-        this.builder.getOptionsBuilder().setAllowAlias(true);
-
-        return this;
-    }
-
-    /*
-     * call-seq:
-     *     EnumBuilder.add_value(name, number)
-     *
-     * Adds the given name => number mapping to the enum type. Name must be a Ruby
-     * symbol.
-     */
-    @JRubyMethod
-    public IRubyObject value(ThreadContext context, IRubyObject name, IRubyObject number) {
-        this.builder.addValueBuilder()
-            .setName(name.asJavaString())
-            .setNumber(RubyNumeric.num2int(number));
-        return context.nil;
-    }
-
-    private EnumDescriptorProto.Builder builder;
-    private RubyFileBuilderContext fileBuilderContext;
-}
diff --git a/ruby/src/main/java/com/google/protobuf/jruby/RubyEnumDescriptor.java b/ruby/src/main/java/com/google/protobuf/jruby/RubyEnumDescriptor.java
index e9c1f10..26f00db 100644
--- a/ruby/src/main/java/com/google/protobuf/jruby/RubyEnumDescriptor.java
+++ b/ruby/src/main/java/com/google/protobuf/jruby/RubyEnumDescriptor.java
@@ -35,6 +35,7 @@
 import com.google.protobuf.DescriptorProtos.EnumDescriptorProto;
 import com.google.protobuf.Descriptors.EnumDescriptor;
 import com.google.protobuf.Descriptors.EnumValueDescriptor;
+import com.google.protobuf.Descriptors.FileDescriptor;
 import org.jruby.Ruby;
 import org.jruby.RubyClass;
 import org.jruby.RubyModule;
@@ -151,6 +152,7 @@
         Ruby runtime = context.runtime;
 
         RubyModule enumModule = RubyModule.newModule(runtime);
+        boolean defaultValueRequiredButNotFound = descriptor.getFile().getSyntax() == FileDescriptor.Syntax.PROTO3;
         for (EnumValueDescriptor value : descriptor.getValues()) {
             String name = value.getName();
             // Make sure its a valid constant name before trying to create it
@@ -159,8 +161,14 @@
             } else {
                 runtime.getWarnings().warn("Enum value " + name + " does not start with an uppercase letter as is required for Ruby constants.");
             }
+            if (value.getNumber() == 0) {
+                defaultValueRequiredButNotFound = false;
+            }
         }
 
+        if (defaultValueRequiredButNotFound) {
+            throw Utils.createTypeError(context, "Enum definition " + name + " does not contain a value for '0'");
+        }
         enumModule.instance_variable_set(runtime.newString(Utils.DESCRIPTOR_INSTANCE_VAR), this);
         enumModule.defineAnnotatedMethods(RubyEnum.class);
         return enumModule;
diff --git a/ruby/src/main/java/com/google/protobuf/jruby/RubyFieldDescriptor.java b/ruby/src/main/java/com/google/protobuf/jruby/RubyFieldDescriptor.java
index 8ac5e4c..e9594d8 100644
--- a/ruby/src/main/java/com/google/protobuf/jruby/RubyFieldDescriptor.java
+++ b/ruby/src/main/java/com/google/protobuf/jruby/RubyFieldDescriptor.java
@@ -32,8 +32,8 @@
 
 package com.google.protobuf.jruby;
 
-import com.google.protobuf.Descriptors.Descriptor;
 import com.google.protobuf.Descriptors.FieldDescriptor;
+import com.google.protobuf.Descriptors.FileDescriptor;
 import org.jruby.*;
 import org.jruby.anno.JRubyClass;
 import org.jruby.anno.JRubyMethod;
@@ -228,6 +228,9 @@
     }
 
     protected void setDescriptor(ThreadContext context, FieldDescriptor descriptor, RubyDescriptorPool pool) {
+        if (descriptor.isRequired() && descriptor.getFile().getSyntax() == FileDescriptor.Syntax.PROTO3) {
+            throw Utils.createTypeError(context, descriptor.getName() + " is labeled required but required fields are unsupported in proto3");
+        }
         this.descriptor = descriptor;
         this.name = context.runtime.newString(descriptor.getName());
         this.pool = pool;
diff --git a/ruby/src/main/java/com/google/protobuf/jruby/RubyFileBuilderContext.java b/ruby/src/main/java/com/google/protobuf/jruby/RubyFileBuilderContext.java
deleted file mode 100644
index 00ce3f2..0000000
--- a/ruby/src/main/java/com/google/protobuf/jruby/RubyFileBuilderContext.java
+++ /dev/null
@@ -1,348 +0,0 @@
-/*
- * Protocol Buffers - Google's data interchange format
- * Copyright 2014 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.
- */
-
-package com.google.protobuf.jruby;
-
-import com.google.protobuf.DescriptorProtos.DescriptorProto;
-import com.google.protobuf.DescriptorProtos.EnumDescriptorProto;
-import com.google.protobuf.DescriptorProtos.EnumValueDescriptorProtoOrBuilder;
-import com.google.protobuf.DescriptorProtos.FieldDescriptorProto;
-import com.google.protobuf.DescriptorProtos.FileDescriptorProto;
-import com.google.protobuf.Descriptors.FieldDescriptor;
-import org.jruby.Ruby;
-import org.jruby.RubyClass;
-import org.jruby.RubyHash;
-import org.jruby.RubyModule;
-import org.jruby.RubyObject;
-import org.jruby.anno.JRubyClass;
-import org.jruby.anno.JRubyMethod;
-import org.jruby.runtime.Block;
-import org.jruby.runtime.ObjectAllocator;
-import org.jruby.runtime.ThreadContext;
-import org.jruby.runtime.builtin.IRubyObject;
-
-import java.util.HashMap;
-import java.util.List;
-import java.util.TreeMap;
-
-@JRubyClass(name = "FileBuilderContext")
-public class RubyFileBuilderContext extends RubyObject {
-    public static void createRubyFileBuilderContext(Ruby runtime) {
-        RubyModule internal = runtime.getClassFromPath("Google::Protobuf::Internal");
-        RubyClass cFileBuilderContext = internal.defineClassUnder("FileBuilderContext", runtime.getObject(), new ObjectAllocator() {
-            @Override
-            public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
-                return new RubyFileBuilderContext(runtime, klazz);
-            }
-        });
-        cFileBuilderContext.defineAnnotatedMethods(RubyFileBuilderContext.class);
-
-        cDescriptor = (RubyClass) runtime.getClassFromPath("Google::Protobuf::Descriptor");
-        cEnumBuilderContext = (RubyClass) runtime.getClassFromPath("Google::Protobuf::Internal::EnumBuilderContext");
-        cEnumDescriptor = (RubyClass) runtime.getClassFromPath("Google::Protobuf::EnumDescriptor");
-        cMessageBuilderContext = (RubyClass) runtime.getClassFromPath("Google::Protobuf::Internal::MessageBuilderContext");
-    }
-
-    public RubyFileBuilderContext(Ruby runtime, RubyClass klazz) {
-        super(runtime, klazz);
-    }
-
-    /*
-     * call-seq:
-     *     FileBuilderContext.new(descriptor_pool, name, options = nil) => context
-     *
-     * Create a new file builder context for the given file descriptor and
-     * builder context. This class is intended to serve as a DSL context to be used
-     * with #instance_eval.
-     */
-    @JRubyMethod(required = 2, optional = 1)
-    public IRubyObject initialize(ThreadContext context, IRubyObject[] args) {
-        this.descriptorPool = (RubyDescriptorPool) args[0];
-        this.builder = FileDescriptorProto.newBuilder();
-        this.builder.setName(args[1].asJavaString());
-        this.builder.setSyntax("proto3");
-
-        if (args.length > 2) {
-            RubyHash options = (RubyHash) args[2];
-            IRubyObject syntax = options.fastARef(context.runtime.newSymbol("syntax"));
-
-            if (syntax != null) {
-                String syntaxStr = syntax.asJavaString();
-                this.builder.setSyntax(syntaxStr);
-                this.proto3 = syntaxStr.equals("proto3");
-            }
-        }
-
-        return this;
-    }
-
-    /*
-     * call-seq:
-     *     FileBuilderContext.add_enum(name, &block)
-     *
-     * Creates a new, empty enum descriptor with the given name, and invokes the
-     * block in the context of an EnumBuilderContext on that descriptor. The block
-     * can then call EnumBuilderContext#add_value to define the enum values.
-     *
-     * This is the recommended, idiomatic way to build enum definitions.
-     */
-    @JRubyMethod(name = "add_enum")
-    public IRubyObject addEnum(ThreadContext context, IRubyObject name, Block block) {
-        RubyObject ctx = (RubyObject) cEnumBuilderContext.newInstance(context, this, name, Block.NULL_BLOCK);
-        ctx.instance_eval(context, block);
-
-        return context.nil;
-    }
-
-    /*
-     * call-seq:
-     *     FileBuilderContext.add_message(name, &block)
-     *
-     * Creates a new, empty descriptor with the given name, and invokes the block in
-     * the context of a MessageBuilderContext on that descriptor. The block can then
-     * call, e.g., MessageBuilderContext#optional and MessageBuilderContext#repeated
-     * methods to define the message fields.
-     *
-     * This is the recommended, idiomatic way to build message definitions.
-     */
-    @JRubyMethod(name = "add_message")
-    public IRubyObject addMessage(ThreadContext context, IRubyObject name, Block block) {
-        RubyObject ctx = (RubyObject) cMessageBuilderContext.newInstance(context, this, name, Block.NULL_BLOCK);
-        ctx.instance_eval(context, block);
-
-        return context.nil;
-    }
-
-    protected void build(ThreadContext context) {
-        Ruby runtime = context.runtime;
-        List<DescriptorProto.Builder> messageBuilderList = builder.getMessageTypeBuilderList();
-        List<EnumDescriptorProto.Builder> enumBuilderList = builder.getEnumTypeBuilderList();
-
-        // Get the package name from defined names
-        String packageName = getPackageName(messageBuilderList, enumBuilderList);
-
-        if (!packageName.isEmpty()) {
-            builder.setPackage(packageName);
-        }
-
-        // Make an index of the message builders so we can easily nest them
-        TreeMap<String, DescriptorProto.Builder> messageBuilderMap = new TreeMap();
-        for (DescriptorProto.Builder messageBuilder : messageBuilderList) {
-            messageBuilderMap.put(messageBuilder.getName(), messageBuilder);
-        }
-
-        // Make an index of the enum builders so we can easily nest them
-        HashMap<String, EnumDescriptorProto.Builder> enumBuilderMap = new HashMap();
-        for (EnumDescriptorProto.Builder enumBuilder : enumBuilderList) {
-            enumBuilderMap.put("." + enumBuilder.getName(), enumBuilder);
-        }
-
-        // Rename and properly nest messages and create associated ruby objects
-        int packageNameLength = packageName.length();
-        int currentMessageIndex = 0;
-        int currentEnumIndex = 0;
-
-        // Need to get a static list because we are potentially deleting some of them from the collection
-        DescriptorProto.Builder[] messageBuilders = new DescriptorProto.Builder[messageBuilderList.size()];
-        messageBuilderList.toArray(messageBuilders);
-        EnumDescriptorProto.Builder[] enumBuilders = new EnumDescriptorProto.Builder[enumBuilderList.size()];
-        enumBuilderList.toArray(enumBuilders);
-
-        for (EnumDescriptorProto.Builder enumBuilder : enumBuilders) {
-            String name = enumBuilder.getName();
-            int lastDot = name.lastIndexOf('.');
-
-            if (lastDot > packageNameLength) {
-                String parentName = name.substring(0, lastDot);
-                String shortName = name.substring(lastDot + 1);
-
-                enumBuilder.setName(shortName);
-                messageBuilderMap.get(parentName).addEnumType(enumBuilder);
-
-                builder.removeEnumType(currentEnumIndex);
-
-            } else {
-                if (packageNameLength > 0) {
-                    // Remove the package name
-                    String shortName = name.substring(packageNameLength + 1);
-                    enumBuilder.setName(shortName);
-                }
-
-                currentEnumIndex++;
-            }
-
-            // Ensure we have a default value if using proto3 syntax
-            if (proto3) {
-                boolean foundDefault = false;
-                for (EnumValueDescriptorProtoOrBuilder enumValue : enumBuilder.getValueOrBuilderList()) {
-                    if (enumValue.getNumber() == 0) {
-                        foundDefault = true;
-                        break;
-                    }
-                }
-
-                if (!foundDefault) {
-                    throw Utils.createTypeError(context, "Enum definition " + enumBuilder.getName() + " does not contain a value for '0'");
-                }
-            }
-        }
-
-        // Wipe out top level message builders so we can insert only the ones that should be there
-        builder.clearMessageType();
-
-        /*
-         * This block is done in this order because calling
-         * `addNestedType` and `addMessageType` makes a copy of the builder
-         * so the objects that our maps point to are no longer the objects
-         * that are being used to build the descriptions.
-         */
-        for (HashMap.Entry<String, DescriptorProto.Builder> entry : messageBuilderMap.descendingMap().entrySet()) {
-            DescriptorProto.Builder messageBuilder = entry.getValue();
-
-            // Rewrite any enum defaults needed
-            for(FieldDescriptorProto.Builder field : messageBuilder.getFieldBuilderList()) {
-                String typeName = field.getTypeName();
-
-                if (typeName == null || !field.hasDefaultValue()) continue;
-
-                EnumDescriptorProto.Builder enumBuilder = enumBuilderMap.get(typeName);
-
-                if (enumBuilder == null) continue;
-
-                int defaultValue = Integer.parseInt(field.getDefaultValue());
-
-                for (EnumValueDescriptorProtoOrBuilder enumValue : enumBuilder.getValueOrBuilderList()) {
-                    if (enumValue.getNumber() == defaultValue) {
-                        field.setDefaultValue(enumValue.getName());
-                        break;
-                    }
-                }
-            }
-
-            // Turn Foo.Bar.Baz into a correctly nested structure with the correct name
-            String name = messageBuilder.getName();
-            int lastDot = name.lastIndexOf('.');
-
-            if (lastDot > packageNameLength) {
-                String parentName = name.substring(0, lastDot);
-                String shortName = name.substring(lastDot + 1);
-                messageBuilder.setName(shortName);
-                messageBuilderMap.get(parentName).addNestedType(messageBuilder);
-
-            } else {
-                if (packageNameLength > 0) {
-                    // Remove the package name
-                    messageBuilder.setName(name.substring(packageNameLength + 1));
-                }
-
-                // Add back in top level message definitions
-                builder.addMessageType(messageBuilder);
-
-                currentMessageIndex++;
-            }
-        }
-
-        descriptorPool.registerFileDescriptor(context, builder);
-    }
-
-    protected EnumDescriptorProto.Builder getNewEnumBuilder() {
-        return builder.addEnumTypeBuilder();
-    }
-
-    protected DescriptorProto.Builder getNewMessageBuilder() {
-        return builder.addMessageTypeBuilder();
-    }
-
-    protected boolean isProto3() {
-        return proto3;
-    }
-
-    private String getPackageName(List<DescriptorProto.Builder> messages, List<EnumDescriptorProto.Builder> enums) {
-        String shortest = null;
-        String longest = null;
-
-        /*
-         * The >= in the longest string comparisons below makes it so we replace
-         * the name in case all the names are the same length. This makes it so
-         * that the shortest and longest aren't the same name to prevent
-         * finding a "package" that isn't correct
-         */
-
-        for (DescriptorProto.Builder message : messages) {
-            String name = message.getName();
-            int nameLength = name.length();
-            if (shortest == null) {
-                shortest = name;
-                longest = name;
-            } else if (nameLength < shortest.length()) {
-                shortest = name;
-            } else if (nameLength >= longest.length()) {
-                longest = name;
-            }
-        }
-
-        for (EnumDescriptorProto.Builder item : enums) {
-            String name = item.getName();
-            int nameLength = name.length();
-            if (shortest == null) {
-                shortest = name;
-                longest = name;
-            } else if (nameLength < shortest.length()) {
-                shortest = name;
-            } else if (nameLength >= longest.length()) {
-                longest = name;
-            }
-        }
-
-        if (shortest == null) {
-            return "";
-        }
-
-        int lastCommonDot = 0;
-        for (int i = 0; i < shortest.length(); i++) {
-            char nextChar = shortest.charAt(i);
-            if (nextChar != longest.charAt(i)) break;
-            if (nextChar == '.') lastCommonDot = i;
-        }
-
-        return shortest.substring(0, lastCommonDot);
-    }
-
-    private static RubyClass cDescriptor;
-    private static RubyClass cEnumBuilderContext;
-    private static RubyClass cEnumDescriptor;
-    private static RubyClass cMessageBuilderContext;
-
-    private FileDescriptorProto.Builder builder;
-    private RubyDescriptorPool descriptorPool;
-    private boolean proto3 = true;
-}
diff --git a/ruby/src/main/java/com/google/protobuf/jruby/RubyMap.java b/ruby/src/main/java/com/google/protobuf/jruby/RubyMap.java
index 087f1cb..8140ec5 100644
--- a/ruby/src/main/java/com/google/protobuf/jruby/RubyMap.java
+++ b/ruby/src/main/java/com/google/protobuf/jruby/RubyMap.java
@@ -37,7 +37,6 @@
 import org.jruby.*;
 import org.jruby.anno.JRubyClass;
 import org.jruby.anno.JRubyMethod;
-import org.jruby.internal.runtime.methods.DynamicMethod;
 import org.jruby.runtime.Block;
 import org.jruby.runtime.Helpers;
 import org.jruby.runtime.ObjectAllocator;
@@ -80,11 +79,12 @@
      * on the same values as field-type symbols in message descriptors) that
      * indicate the type of the map key and value fields.
      *
-     * The supported key types are: :int32, :int64, :uint32, :uint64, :bool,
-     * :string, :bytes.
+     * The supported key types are: :int32, :int64, :uint32, :uint64, :fixed32,
+     * :fixed64, :sfixed32, :sfixed64, :sint32, :sint64, :bool, :string, :bytes.
      *
-     * The supported value types are: :int32, :int64, :uint32, :uint64, :bool,
-     * :string, :bytes, :enum, :message.
+     * The supported value types are: :int32, :int64, :uint32, :uint64, :fixed32,
+     * :fixed64, :sfixed32, :sfixed64, :sint32, :sint64, :bool, :string, :bytes,
+     * :enum, :message.
      *
      * The third argument, value_typeclass, must be present if value_type is :enum
      * or :message. As in RepeatedField#new, this argument must be a message class
@@ -113,8 +113,14 @@
                 break;
             case INT32:
             case INT64:
+            case SINT32:
+            case SINT64:
             case UINT32:
             case UINT64:
+            case FIXED32:
+            case FIXED64:
+            case SFIXED32:
+            case SFIXED64:
             case BOOL:
                 // These are OK.
                 break;
@@ -154,7 +160,7 @@
          * other types for keys, so deal with them specifically first
          */
         if (keyTypeIsString && !(key instanceof RubySymbol || key instanceof RubyString)) {
-            throw context.runtime.newTypeError("Expected string for map key");
+            throw Utils.createTypeError(context, "Expected string for map key");
         }
         key = Utils.checkType(context, keyType, "key", key, (RubyModule) valueTypeClass);
         value = Utils.checkType(context, valueType, "value", value, (RubyModule) valueTypeClass);
@@ -399,7 +405,7 @@
 
     protected RubyMap mergeIntoSelf(final ThreadContext context, IRubyObject hashmap) {
         if (hashmap instanceof RubyHash) {
-            ((RubyHash) hashmap).visitAll(new RubyHash.Visitor() {
+            ((RubyHash) hashmap).visitAll(context, new RubyHash.Visitor() {
                 @Override
                 public void visit(IRubyObject key, IRubyObject val) {
                     if (val instanceof RubyHash && !valueTypeClass.isNil()) {
@@ -407,14 +413,14 @@
                     }
                     indexSet(context, key, val);
                 }
-            });
+            }, null);
         } else if (hashmap instanceof RubyMap) {
             RubyMap other = (RubyMap) hashmap;
             if (!typeCompatible(other)) {
                 throw Utils.createTypeError(context, "Attempt to merge Map with mismatching types");
             }
         } else {
-            throw context.runtime.newTypeError("Unknown type merging into Map");
+            throw Utils.createTypeError(context, "Unknown type merging into Map");
         }
         return this;
     }
diff --git a/ruby/src/main/java/com/google/protobuf/jruby/RubyMessage.java b/ruby/src/main/java/com/google/protobuf/jruby/RubyMessage.java
index a905c9a..cf59f62 100644
--- a/ruby/src/main/java/com/google/protobuf/jruby/RubyMessage.java
+++ b/ruby/src/main/java/com/google/protobuf/jruby/RubyMessage.java
@@ -93,16 +93,18 @@
                 throw runtime.newArgumentError("expected Hash arguments.");
             }
             RubyHash hash = args[0].convertToHash();
-            hash.visitAll(new RubyHash.Visitor() {
+            hash.visitAll(context, new RubyHash.Visitor() {
                 @Override
                 public void visit(IRubyObject key, IRubyObject value) {
-                    if (!(key instanceof RubySymbol) && !(key instanceof RubyString))
-                        throw runtime.newTypeError("Expected string or symbols as hash keys in initialization map.");
+                    if (!(key instanceof RubySymbol) && !(key instanceof RubyString)) {
+                        throw Utils.createTypeError(context,
+                            "Expected string or symbols as hash keys in initialization map.");
+                    }
                     final FieldDescriptor fieldDescriptor = findField(context, key, ignoreUnknownFieldsOnInit);
 
                     if (value == null || value.isNil()) return;
 
-                    if (Utils.isMapEntry(fieldDescriptor)) {
+                    if (fieldDescriptor.isMapField()) {
                         if (!(value instanceof RubyHash))
                             throw runtime.newArgumentError("Expected Hash object as initializer value for map field '" +  key.asJavaString() + "' (given " + value.getMetaClass() + ").");
 
@@ -130,7 +132,7 @@
 
                     }
                 }
-            });
+            }, null);
         }
         return this;
     }
@@ -181,6 +183,9 @@
         sb.append(cname).append(colon);
 
         for (FieldDescriptor fd : descriptor.getFields()) {
+            if (fd.hasPresence() && !fields.containsKey(fd)) {
+                continue;
+            }
             if (addComma) {
                 sb.append(comma);
             } else {
@@ -346,9 +351,11 @@
                 fieldDescriptor = descriptor.findFieldByName(methodName);
 
                 if (fieldDescriptor != null &&
-                        (!proto3 || fieldDescriptor.getContainingOneof() == null) && // This seems like a bug but its needed to pass the tests...
-                        fieldHasPresence(fieldDescriptor)) {
-                    return fields.containsKey(fieldDescriptor) ? runtime.getTrue() : runtime.getFalse();
+                    (!proto3 || fieldDescriptor.getContainingOneof() == null || fieldDescriptor
+                        .getContainingOneof().isSynthetic()) &&
+                    fieldDescriptor.hasPresence()) {
+                    return fields.containsKey(fieldDescriptor) ? runtime.getTrue()
+                        : runtime.getFalse();
                 }
 
             } else if (methodName.endsWith(AS_VALUE_SUFFIX)) {
@@ -428,12 +435,11 @@
     @JRubyMethod
     public IRubyObject dup(ThreadContext context) {
         RubyMessage dup = (RubyMessage) metaClass.newInstance(context, Block.NULL_BLOCK);
-        IRubyObject value;
         for (FieldDescriptor fieldDescriptor : this.descriptor.getFields()) {
             if (fieldDescriptor.isRepeated()) {
                 dup.fields.put(fieldDescriptor, this.getRepeatedField(context, fieldDescriptor));
             } else if (fields.containsKey(fieldDescriptor)) {
-                dup.fields.put(fieldDescriptor, fields.get(fieldDescriptor));
+                dup.setFieldInternal(context, fieldDescriptor, fields.get(fieldDescriptor));
             } else if (this.builder.hasField(fieldDescriptor)) {
                 dup.fields.put(fieldDescriptor, wrapField(context, fieldDescriptor, this.builder.getField(fieldDescriptor)));
             }
@@ -474,7 +480,7 @@
      *     MessageClass.decode(data) => message
      *
      * Decodes the given data (as a string containing bytes in protocol buffers wire
-     * format) under the interpretration given by this message class's definition
+     * format) under the interpretation given by this message class's definition
      * and returns a message object with the corresponding field values.
      */
     @JRubyMethod(meta = true)
@@ -532,11 +538,14 @@
                 printer = printer.preservingProtoFieldNames();
             }
         }
+        printer = printer.usingTypeRegistry(JsonFormat.TypeRegistry.newBuilder().add(message.descriptor).build());
 
         try {
             result = printer.print(message.build(context));
-        } catch(InvalidProtocolBufferException e) {
+        } catch (InvalidProtocolBufferException e) {
             throw runtime.newRuntimeError(e.getMessage());
+        } catch (IllegalArgumentException e) {
+            throw createParseError(context, e.getMessage());
         }
 
         return runtime.newString(result);
@@ -547,7 +556,7 @@
      *     MessageClass.decode_json(data, options = {}) => message
      *
      * Decodes the given data (as a string containing bytes in protocol buffers wire
-     * format) under the interpretration given by this message class's definition
+     * format) under the interpretation given by this message class's definition
      * and returns a message object with the corresponding field values.
      *
      *  @param options [Hash] options for the decoder
@@ -577,6 +586,7 @@
         }
 
         RubyMessage ret = (RubyMessage) ((RubyClass) recv).newInstance(context, Block.NULL_BLOCK);
+        parser = parser.usingTypeRegistry(JsonFormat.TypeRegistry.newBuilder().add(ret.descriptor).build());
 
         try {
             parser.merge(data.asJavaString(), ret.builder);
@@ -633,6 +643,8 @@
         if (depth > SINK_MAXIMUM_NESTING) {
             throw context.runtime.newRuntimeError("Maximum recursion depth exceeded during encoding.");
         }
+
+        // Handle the typical case where the fields.keySet contain the fieldDescriptors
         for (FieldDescriptor fieldDescriptor : fields.keySet()) {
             IRubyObject value = fields.get(fieldDescriptor);
 
@@ -648,15 +660,53 @@
 
                 builder.clearField(fieldDescriptor);
                 for (int i = 0; i < repeatedField.size(); i++) {
-                    Object item = convert(context, fieldDescriptor, repeatedField.get(i), depth);
+                    Object item = convert(context, fieldDescriptor, repeatedField.get(i), depth,
+                        /*isDefaultValueForBytes*/ false);
                     builder.addRepeatedField(fieldDescriptor, item);
                 }
 
-            } else {
-                builder.setField(fieldDescriptor, convert(context, fieldDescriptor, value, depth));
+            } else if (!value.isNil()) {
+                /**
+                 * Detect the special case where default_value strings are provided for byte fields.
+                 * If so, disable normal string encoding behavior within convert.
+                 * For a more detailed explanation of other possible workarounds, see the comments
+                 * above {@code com.google.protobuf.Internal#stringDefaultValue()
+                 * stringDefaultValue}.
+                 */
+                boolean isDefaultStringForBytes = false;
+                FieldDescriptor enumFieldDescriptorForType =
+                    this.builder.getDescriptorForType().findFieldByName("type");
+                String type = enumFieldDescriptorForType == null ?
+                    null : fields.get(enumFieldDescriptorForType).toString();
+                if (type != null && type.equals("TYPE_BYTES") &&
+                    fieldDescriptor.getFullName().equals("google.protobuf.FieldDescriptorProto.default_value")) {
+                    isDefaultStringForBytes = true;
+                }
+                builder.setField(fieldDescriptor, convert(context, fieldDescriptor, value, depth, isDefaultStringForBytes));
             }
         }
 
+        // Handle cases where {@code fields} doesn't contain the value until after getFieldInternal
+        // is called - typical of a deserialized message. Skip non-maps and descriptors that already
+        // have an entry in {@code fields}.
+        for (FieldDescriptor fieldDescriptor : descriptor.getFields()) {
+            if (!fieldDescriptor.isMapField()) {
+                continue;
+            }
+            IRubyObject value = fields.get(fieldDescriptor);
+            if (value!=null) {
+                continue;
+            }
+            value = getFieldInternal(context, fieldDescriptor);
+            if (value instanceof RubyMap) {
+                builder.clearField(fieldDescriptor);
+                RubyDescriptor mapDescriptor = (RubyDescriptor) getDescriptorForField(context,
+                    fieldDescriptor);
+                for (DynamicMessage kv : ((RubyMap) value).build(context, mapDescriptor, depth)) {
+                    builder.addRepeatedField(fieldDescriptor, kv);
+                }
+            }
+        }
         return builder.build();
     }
 
@@ -667,7 +717,7 @@
             if (fdef.isRepeated()) {
                 copy.fields.put(fdef, this.getRepeatedField(context, fdef).deepCopy(context));
             } else if (fields.containsKey(fdef)) {
-                copy.fields.put(fdef, fields.get(fdef));
+                copy.setFieldInternal(context, fdef, fields.get(fdef));
             } else if (builder.hasField(fdef)) {
                 copy.fields.put(fdef, wrapField(context, fdef, builder.getField(fdef)));
             }
@@ -691,7 +741,9 @@
 
     protected IRubyObject hasField(ThreadContext context, FieldDescriptor fieldDescriptor) {
         validateMessageType(context, fieldDescriptor, "has?");
-        if (!fieldHasPresence(fieldDescriptor)) throw context.runtime.newArgumentError("does not track presence");
+        if (!fieldDescriptor.hasPresence()) {
+            throw context.runtime.newArgumentError("does not track presence");
+        }
         return fields.containsKey(fieldDescriptor) ? context.runtime.getTrue() : context.runtime.getFalse();
     }
 
@@ -762,19 +814,24 @@
     // convert a ruby object to protobuf type, skip type check since it is checked on the way in
     private Object convert(ThreadContext context,
                            FieldDescriptor fieldDescriptor,
-                           IRubyObject value, int depth) {
-        Ruby runtime = context.runtime;
+                           IRubyObject value, int depth, boolean isDefaultStringForBytes) {
         Object val = null;
         switch (fieldDescriptor.getType()) {
             case INT32:
+            case SFIXED32:
+            case SINT32:
                 val = RubyNumeric.num2int(value);
                 break;
             case INT64:
+            case SFIXED64:
+            case SINT64:
                 val = RubyNumeric.num2long(value);
                 break;
+            case FIXED32:
             case UINT32:
                 val = Utils.num2uint(value);
                 break;
+            case FIXED64:
             case UINT64:
                 val = Utils.num2ulong(context.runtime, value);
                 break;
@@ -791,7 +848,11 @@
                 val = ByteString.copyFrom(((RubyString) value).getBytes());
                 break;
             case STRING:
-                val = ((RubyString) value).asJavaString();
+                if (isDefaultStringForBytes) {
+                    val = ((RubyString) value).getByteList().toString();
+                } else {
+                    val = value.asJavaString();
+                }
                 break;
             case MESSAGE:
                 val = ((RubyMessage) value).build(context, depth + 1);
@@ -819,6 +880,10 @@
     }
 
     private IRubyObject wrapField(ThreadContext context, FieldDescriptor fieldDescriptor, Object value) {
+        return wrapField(context, fieldDescriptor, value, false);
+    }
+
+    private IRubyObject wrapField(ThreadContext context, FieldDescriptor fieldDescriptor, Object value, boolean encodeBytes) {
         if (value == null) {
             return context.runtime.getNil();
         }
@@ -827,6 +892,12 @@
         switch (fieldDescriptor.getType()) {
             case INT32:
             case INT64:
+            case FIXED32:
+            case SINT32:
+            case FIXED64:
+            case SINT64:
+            case SFIXED64:
+            case SFIXED32:
             case UINT32:
             case UINT64:
             case FLOAT:
@@ -834,7 +905,7 @@
             case BOOL:
             case BYTES:
             case STRING:
-                return Utils.wrapPrimaryValue(context, fieldDescriptor.getType(), value);
+                return Utils.wrapPrimaryValue(context, fieldDescriptor.getType(), value, encodeBytes);
             case MESSAGE:
                 RubyClass typeClass = (RubyClass) ((RubyDescriptor) getDescriptorForField(context, fieldDescriptor)).msgclass(context);
                 RubyMessage msg = (RubyMessage) typeClass.newInstance(context, Block.NULL_BLOCK);
@@ -872,22 +943,44 @@
         return getFieldInternal(context, fieldDescriptor, true);
     }
 
-    private IRubyObject getFieldInternal(ThreadContext context, FieldDescriptor fieldDescriptor, boolean returnDefaults) {
+    private IRubyObject getFieldInternal(ThreadContext context, FieldDescriptor fieldDescriptor,
+        boolean returnDefaults) {
         OneofDescriptor oneofDescriptor = fieldDescriptor.getContainingOneof();
         if (oneofDescriptor != null) {
             if (oneofCases.get(oneofDescriptor) == fieldDescriptor) {
-                return fields.get(fieldDescriptor);
+                IRubyObject value = fields.get(fieldDescriptor);
+                if (value == null) {
+                    FieldDescriptor oneofCase = builder.getOneofFieldDescriptor(oneofDescriptor);
+                    if (oneofCase != null) {
+                        Object builderValue = builder.getField(oneofCase);
+                        if (builderValue != null) {
+                            boolean encodeBytes = oneofCase.hasDefaultValue() && builderValue.equals(oneofCase.getDefaultValue());
+                            value = wrapField(context, oneofCase, builderValue, encodeBytes);
+                        }
+                    }
+                    if (value == null) {
+                        return context.nil;
+                    } else {
+                        return value;
+                    }
+                } else {
+                    return value;
+                }
             } else {
                 FieldDescriptor oneofCase = builder.getOneofFieldDescriptor(oneofDescriptor);
                 if (oneofCase != fieldDescriptor) {
-                  if (fieldDescriptor.getType() == FieldDescriptor.Type.MESSAGE || !returnDefaults) {
-                    return context.nil;
-                  } else {
-                    return wrapField(context, fieldDescriptor, fieldDescriptor.getDefaultValue());
-                  }
+                    if (fieldDescriptor.getType() == FieldDescriptor.Type.MESSAGE
+                        || !returnDefaults) {
+                        return context.nil;
+                    } else {
+                        return wrapField(context, fieldDescriptor,
+                            fieldDescriptor.getDefaultValue(), true);
+                    }
                 }
                 if (returnDefaults || builder.hasField(fieldDescriptor)) {
-                    IRubyObject value = wrapField(context, oneofCase, builder.getField(oneofCase));
+                    Object rawValue = builder.getField(oneofCase);
+                    boolean encodeBytes = oneofCase.hasDefaultValue() && rawValue.equals(oneofCase.getDefaultValue());
+                    IRubyObject value = wrapField(context, oneofCase, rawValue, encodeBytes);
                     fields.put(fieldDescriptor, value);
                     return value;
                 } else {
@@ -896,7 +989,7 @@
             }
         }
 
-        if (Utils.isMapEntry(fieldDescriptor)) {
+        if (fieldDescriptor.isMapField()) {
             RubyMap map = (RubyMap) fields.get(fieldDescriptor);
             if (map == null) {
                 map = newMapForField(context, fieldDescriptor);
@@ -925,7 +1018,9 @@
             if (fields.containsKey(fieldDescriptor)) {
                 return fields.get(fieldDescriptor);
             } else if (returnDefaults || builder.hasField(fieldDescriptor)) {
-                IRubyObject value = wrapField(context, fieldDescriptor, builder.getField(fieldDescriptor));
+                Object rawValue = builder.getField(fieldDescriptor);
+                boolean encodeBytes = fieldDescriptor.hasDefaultValue() && rawValue.equals(fieldDescriptor.getDefaultValue());
+                IRubyObject value = wrapField(context, fieldDescriptor, rawValue, encodeBytes);
                 if (builder.hasField(fieldDescriptor)) {
                     fields.put(fieldDescriptor, value);
                 }
@@ -938,7 +1033,7 @@
     private IRubyObject setFieldInternal(ThreadContext context, FieldDescriptor fieldDescriptor, IRubyObject value) {
         testFrozen("can't modify frozen " + getMetaClass());
 
-        if (Utils.isMapEntry(fieldDescriptor)) {
+        if (fieldDescriptor.isMapField()) {
             if (!(value instanceof RubyMap)) {
                 throw Utils.createTypeError(context, "Expected Map instance");
             }
@@ -980,7 +1075,9 @@
                 // Keep track of what Oneofs are set
                 if (value.isNil()) {
                     oneofCases.remove(oneofDescriptor);
-                    addValue = false;
+                    if (!oneofDescriptor.isSynthetic()) {
+                        addValue = false;
+                    }
                 } else {
                     oneofCases.put(oneofDescriptor, fieldDescriptor);
                 }
@@ -1019,20 +1116,12 @@
         return context.runtime.newSymbol("UNKNOWN");
     }
 
-    private boolean fieldHasPresence(FieldDescriptor fieldDescriptor) {
-      return !fieldDescriptor.isRepeated() &&
-              (fieldDescriptor.getType() == FieldDescriptor.Type.MESSAGE ||
-                fieldDescriptor.getContainingOneof() != null ||
-                !proto3);
-    }
-
     private RubyRepeatedField rubyToRepeatedField(ThreadContext context,
                                                   FieldDescriptor fieldDescriptor, IRubyObject value) {
         RubyArray arr = value.convertToArray();
         RubyRepeatedField repeatedField = repeatedFieldForFieldDescriptor(context, fieldDescriptor);
         IRubyObject[] values = new IRubyObject[arr.size()];
         FieldDescriptor.Type fieldType = fieldDescriptor.getType();
-        String fieldName = fieldDescriptor.getName();
 
         RubyModule typeClass = null;
         if (fieldType == FieldDescriptor.Type.MESSAGE) {
@@ -1045,8 +1134,11 @@
 
         for (int i = 0; i < arr.size(); i++) {
             IRubyObject item = arr.eltInternal(i);
+            if (item.isNil()) {
+                throw Utils.createTypeError(context, "nil message not allowed here.");
+            }
             if (item instanceof RubyHash && typeClass != null) {
-                values[i] = (IRubyObject) ((RubyClass) typeClass).newInstance(context, item, Block.NULL_BLOCK);
+                values[i] = ((RubyClass) typeClass).newInstance(context, item, Block.NULL_BLOCK);
             } else {
                 if (fieldType == FieldDescriptor.Type.ENUM) {
                     item = enumToSymbol(context, fieldDescriptor.getEnumType(), item);
@@ -1086,13 +1178,6 @@
         }
     }
 
-    private FieldDescriptor getOneofCase(OneofDescriptor oneof) {
-        if (oneofCases.containsKey(oneof)) {
-            return oneofCases.get(oneof);
-        }
-        return builder.getOneofFieldDescriptor(oneof);
-    }
-
     private boolean isWrappable(FieldDescriptor fieldDescriptor) {
       if (fieldDescriptor.getType() != FieldDescriptor.Type.MESSAGE) return false;
 
@@ -1118,7 +1203,7 @@
 
     private void validateMessageType(ThreadContext context, FieldDescriptor fieldDescriptor, String methodName) {
         if (descriptor != fieldDescriptor.getContainingType()) {
-            throw context.runtime.newTypeError(methodName + " method called on wrong message type");
+            throw Utils.createTypeError(context, methodName + " method called on wrong message type");
         }
     }
 
@@ -1139,6 +1224,4 @@
     private RubyClass cMap;
     private boolean ignoreUnknownFieldsOnInit = false;
     private boolean proto3;
-
-
 }
diff --git a/ruby/src/main/java/com/google/protobuf/jruby/RubyMessageBuilderContext.java b/ruby/src/main/java/com/google/protobuf/jruby/RubyMessageBuilderContext.java
deleted file mode 100644
index 211236c..0000000
--- a/ruby/src/main/java/com/google/protobuf/jruby/RubyMessageBuilderContext.java
+++ /dev/null
@@ -1,255 +0,0 @@
-/*
- * Protocol Buffers - Google's data interchange format
- * Copyright 2014 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.
- */
-
-package com.google.protobuf.jruby;
-
-import com.google.protobuf.DescriptorProtos.DescriptorProto;
-import com.google.protobuf.DescriptorProtos.FieldDescriptorProto;
-import com.google.protobuf.DescriptorProtos.OneofDescriptorProto;
-import org.jruby.*;
-import org.jruby.anno.JRubyClass;
-import org.jruby.anno.JRubyMethod;
-import org.jruby.runtime.Binding;
-import org.jruby.runtime.Block;
-import org.jruby.runtime.ObjectAllocator;
-import org.jruby.runtime.ThreadContext;
-import org.jruby.runtime.builtin.IRubyObject;
-
-@JRubyClass(name = "MessageBuilderContext")
-public class RubyMessageBuilderContext extends RubyObject {
-    public static void createRubyMessageBuilderContext(Ruby runtime) {
-        RubyModule internal = runtime.getClassFromPath("Google::Protobuf::Internal");
-        RubyClass cMessageBuilderContext = internal.defineClassUnder("MessageBuilderContext", runtime.getObject(), new ObjectAllocator() {
-            @Override
-            public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
-                return new RubyMessageBuilderContext(runtime, klazz);
-            }
-        });
-        cMessageBuilderContext.defineAnnotatedMethods(RubyMessageBuilderContext.class);
-
-        cFieldDescriptor = (RubyClass) runtime.getClassFromPath("Google::Protobuf::FieldDescriptor");
-        cOneofBuilderContext = (RubyClass) runtime.getClassFromPath("Google::Protobuf::Internal::OneofBuilderContext");
-    }
-
-    public RubyMessageBuilderContext(Ruby runtime, RubyClass klazz) {
-        super(runtime, klazz);
-    }
-
-    @JRubyMethod
-    public IRubyObject initialize(ThreadContext context, IRubyObject fileBuilderContext, IRubyObject name) {
-        this.fileBuilderContext = (RubyFileBuilderContext) fileBuilderContext;
-        this.builder = this.fileBuilderContext.getNewMessageBuilder();
-        this.builder.setName(name.asJavaString());
-
-        return this;
-    }
-
-    /*
-     * call-seq:
-     *     MessageBuilderContext.optional(name, type, number, type_class = nil,
-     *                                    options = nil)
-     *
-     * Defines a new optional field on this message type with the given type, tag
-     * number, and type class (for message and enum fields). The type must be a Ruby
-     * symbol (as accepted by FieldDescriptor#type=) and the type_class must be a
-     * string, if present (as accepted by FieldDescriptor#submsg_name=).
-     */
-    @JRubyMethod(required = 3, optional = 2)
-    public IRubyObject optional(ThreadContext context, IRubyObject[] args) {
-        addField(context, OPTIONAL, args, false);
-        return context.nil;
-    }
-
-    @JRubyMethod(required = 3, optional = 2)
-    public IRubyObject proto3_optional(ThreadContext context, IRubyObject[] args) {
-      addField(context, OPTIONAL, args, true);
-      return context.nil;
-    }
-
-    /*
-     * call-seq:
-     *     MessageBuilderContext.required(name, type, number, type_class = nil,
-     *                                    options = nil)
-     *
-     * Defines a new required field on this message type with the given type, tag
-     * number, and type class (for message and enum fields). The type must be a Ruby
-     * symbol (as accepted by FieldDescriptor#type=) and the type_class must be a
-     * string, if present (as accepted by FieldDescriptor#submsg_name=).
-     *
-     * Proto3 does not have required fields, but this method exists for
-     * completeness. Any attempt to add a message type with required fields to a
-     * pool will currently result in an error.
-     */
-    @JRubyMethod(required = 3, optional = 2)
-    public IRubyObject required(ThreadContext context, IRubyObject[] args) {
-        if (fileBuilderContext.isProto3()) throw Utils.createTypeError(context, "Required fields are unsupported in proto3");
-        addField(context, "required", args, false);
-        return context.nil;
-    }
-
-    /*
-     * call-seq:
-     *     MessageBuilderContext.repeated(name, type, number, type_class = nil)
-     *
-     * Defines a new repeated field on this message type with the given type, tag
-     * number, and type class (for message and enum fields). The type must be a Ruby
-     * symbol (as accepted by FieldDescriptor#type=) and the type_class must be a
-     * string, if present (as accepted by FieldDescriptor#submsg_name=).
-     */
-    @JRubyMethod(required = 3, optional = 1)
-    public IRubyObject repeated(ThreadContext context, IRubyObject[] args) {
-        addField(context, "repeated", args, false);
-        return context.nil;
-    }
-
-    /*
-     * call-seq:
-     *     MessageBuilderContext.map(name, key_type, value_type, number,
-     *                               value_type_class = nil)
-     *
-     * Defines a new map field on this message type with the given key and value
-     * types, tag number, and type class (for message and enum value types). The key
-     * type must be :int32/:uint32/:int64/:uint64, :bool, or :string. The value type
-     * type must be a Ruby symbol (as accepted by FieldDescriptor#type=) and the
-     * type_class must be a string, if present (as accepted by
-     * FieldDescriptor#submsg_name=).
-     */
-    @JRubyMethod(required = 4, optional = 1)
-    public IRubyObject map(ThreadContext context, IRubyObject[] args) {
-        Ruby runtime = context.runtime;
-        if (!fileBuilderContext.isProto3()) throw runtime.newArgumentError("Cannot add a native map field using proto2 syntax.");
-
-        RubySymbol messageSym = runtime.newSymbol("message");
-
-        IRubyObject name = args[0];
-        IRubyObject keyType = args[1];
-        IRubyObject valueType = args[2];
-        IRubyObject number = args[3];
-        IRubyObject typeClass = args.length > 4 ? args[4] : context.nil;
-
-        // Validate the key type. We can't accept enums, messages, or floats/doubles
-        // as map keys. (We exclude these explicitly, and the field-descriptor setter
-        // below then ensures that the type is one of the remaining valid options.)
-        if (keyType.equals(runtime.newSymbol("float")) ||
-                keyType.equals(runtime.newSymbol("double")) ||
-                keyType.equals(runtime.newSymbol("enum")) ||
-                keyType.equals(messageSym))
-            throw runtime.newArgumentError("Cannot add a map field with a float, double, enum, or message type.");
-
-        DescriptorProto.Builder mapEntryBuilder = fileBuilderContext.getNewMessageBuilder();
-        mapEntryBuilder.setName(builder.getName() + "_MapEntry_" + name.asJavaString());
-        mapEntryBuilder.getOptionsBuilder().setMapEntry(true);
-
-        mapEntryBuilder.addField(
-            Utils.createFieldBuilder(
-                context,
-                OPTIONAL,
-                new IRubyObject[] {
-                    runtime.newString("key"),
-                    keyType,
-                    runtime.newFixnum(1)
-                }
-            )
-        );
-
-        mapEntryBuilder.addField(
-            Utils.createFieldBuilder(
-                context,
-                OPTIONAL,
-                new IRubyObject[] {
-                    runtime.newString("value"),
-                    valueType,
-                    runtime.newFixnum(2),
-                    typeClass
-                }
-            )
-        );
-
-        IRubyObject[] addFieldArgs = {
-            name, messageSym, number, runtime.newString(mapEntryBuilder.getName())
-        };
-
-        repeated(context, addFieldArgs);
-
-        return context.nil;
-    }
-
-    /*
-     * call-seq:
-     *     MessageBuilderContext.oneof(name, &block) => nil
-     *
-     * Creates a new OneofDescriptor with the given name, creates a
-     * OneofBuilderContext attached to that OneofDescriptor, evaluates the given
-     * block in the context of that OneofBuilderContext with #instance_eval, and
-     * then adds the oneof to the message.
-     *
-     * This is the recommended, idiomatic way to build oneof definitions.
-     */
-    @JRubyMethod
-    public IRubyObject oneof(ThreadContext context, IRubyObject name, Block block) {
-        RubyOneofBuilderContext ctx = (RubyOneofBuilderContext)
-                cOneofBuilderContext.newInstance(
-                        context,
-                        context.runtime.newFixnum(builder.getOneofDeclCount()),
-                        this,
-                        Block.NULL_BLOCK
-                );
-
-        builder.addOneofDeclBuilder().setName(name.asJavaString());
-        ctx.instance_eval(context, block);
-
-        return context.nil;
-    }
-
-    protected void addFieldBuilder(FieldDescriptorProto.Builder fieldBuilder) {
-        builder.addField(fieldBuilder);
-    }
-
-    private FieldDescriptorProto.Builder addField(ThreadContext context, String label, IRubyObject[] args, boolean proto3Optional) {
-        FieldDescriptorProto.Builder fieldBuilder =
-                Utils.createFieldBuilder(context, label, args);
-
-        fieldBuilder.setProto3Optional(proto3Optional);
-        builder.addField(fieldBuilder);
-
-        return fieldBuilder;
-    }
-
-    private static RubyClass cFieldDescriptor;
-    private static RubyClass cOneofBuilderContext;
-
-    private static final String OPTIONAL = "optional";
-
-    private DescriptorProto.Builder builder;
-    private RubyClass cDescriptor;
-    private RubyFileBuilderContext fileBuilderContext;
-}
diff --git a/ruby/src/main/java/com/google/protobuf/jruby/RubyOneofBuilderContext.java b/ruby/src/main/java/com/google/protobuf/jruby/RubyOneofBuilderContext.java
deleted file mode 100644
index 1ce500e..0000000
--- a/ruby/src/main/java/com/google/protobuf/jruby/RubyOneofBuilderContext.java
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * Protocol Buffers - Google's data interchange format
- * Copyright 2014 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.
- */
-
-package com.google.protobuf.jruby;
-
-import com.google.protobuf.DescriptorProtos.FieldDescriptorProto;
-import org.jruby.Ruby;
-import org.jruby.RubyClass;
-import org.jruby.RubyHash;
-import org.jruby.RubyModule;
-import org.jruby.RubyNumeric;
-import org.jruby.RubyObject;
-import org.jruby.anno.JRubyClass;
-import org.jruby.anno.JRubyMethod;
-import org.jruby.runtime.ObjectAllocator;
-import org.jruby.runtime.ThreadContext;
-import org.jruby.runtime.builtin.IRubyObject;
-
-@JRubyClass(name = "OneofBuilderContext")
-public class RubyOneofBuilderContext extends RubyObject {
-    public static void createRubyOneofBuilderContext(Ruby runtime) {
-        RubyModule internal = runtime.getClassFromPath("Google::Protobuf::Internal");
-        RubyClass cRubyOneofBuidlerContext = internal.defineClassUnder("OneofBuilderContext", runtime.getObject(), new ObjectAllocator() {
-            @Override
-            public IRubyObject allocate(Ruby ruby, RubyClass rubyClass) {
-                return new RubyOneofBuilderContext(ruby, rubyClass);
-            }
-        });
-        cRubyOneofBuidlerContext.defineAnnotatedMethods(RubyOneofBuilderContext.class);
-    }
-
-    public RubyOneofBuilderContext(Ruby ruby, RubyClass rubyClass) {
-        super(ruby, rubyClass);
-    }
-
-    /*
-     * call-seq:
-     *     OneofBuilderContext.new(oneof_index, message_builder) => context
-     *
-     * Create a new oneof builder context around the given oneof descriptor and
-     * builder context. This class is intended to serve as a DSL context to be used
-     * with #instance_eval.
-     */
-    @JRubyMethod
-    public IRubyObject initialize(ThreadContext context, IRubyObject index, IRubyObject messageBuilder) {
-        this.builder = (RubyMessageBuilderContext) messageBuilder;
-        this.index = RubyNumeric.num2int(index);
-
-        return this;
-    }
-
-    /*
-     * call-seq:
-     *     OneofBuilderContext.optional(name, type, number, type_class = nil,
-     *                                  options = nil)
-     *
-     * Defines a new optional field in this oneof with the given type, tag number,
-     * and type class (for message and enum fields). The type must be a Ruby symbol
-     * (as accepted by FieldDescriptor#type=) and the type_class must be a string,
-     * if present (as accepted by FieldDescriptor#submsg_name=).
-     */
-    @JRubyMethod(required = 3, optional = 2)
-    public IRubyObject optional(ThreadContext context, IRubyObject[] args) {
-        FieldDescriptorProto.Builder fieldBuilder =
-                Utils.createFieldBuilder(context, "optional", args);
-        fieldBuilder.setOneofIndex(index);
-        builder.addFieldBuilder(fieldBuilder);
-
-        return context.nil;
-    }
-
-    private RubyMessageBuilderContext builder;
-    private int index;
-}
diff --git a/ruby/src/main/java/com/google/protobuf/jruby/Utils.java b/ruby/src/main/java/com/google/protobuf/jruby/Utils.java
index 17c1c8d..cd27589 100644
--- a/ruby/src/main/java/com/google/protobuf/jruby/Utils.java
+++ b/ruby/src/main/java/com/google/protobuf/jruby/Utils.java
@@ -35,7 +35,6 @@
 import com.google.protobuf.ByteString;
 import com.google.protobuf.DescriptorProtos.FieldDescriptorProto;
 import com.google.protobuf.Descriptors.FieldDescriptor;
-import org.jcodings.Encoding;
 import org.jcodings.specific.ASCIIEncoding;
 import org.jruby.*;
 import org.jruby.exceptions.RaiseException;
@@ -70,6 +69,12 @@
         Ruby runtime = context.runtime;
 
         switch(fieldType) {
+            case SFIXED32:
+            case SFIXED64:
+            case FIXED64:
+            case SINT64:
+            case SINT32:
+            case FIXED32:
             case INT32:
             case INT64:
             case UINT32:
@@ -83,7 +88,8 @@
                         throw runtime.newRangeError("Non-integral floating point value assigned to integer field '" + fieldName + "' (given " + value.getMetaClass() + ").");
                     }
                 }
-                if (fieldType == FieldDescriptor.Type.UINT32 || fieldType == FieldDescriptor.Type.UINT64) {
+                if (fieldType == FieldDescriptor.Type.UINT32 || fieldType == FieldDescriptor.Type.UINT64 ||
+                    fieldType == FieldDescriptor.Type.FIXED32  || fieldType == FieldDescriptor.Type.FIXED64) {
                     if (((RubyNumeric) value).isNegative()) {
                         throw runtime.newRangeError("Assigning negative value to unsigned integer field '" + fieldName + "' (given " + value.getMetaClass() + ").");
                     }
@@ -94,9 +100,11 @@
                         RubyNumeric.num2int(value);
                         break;
                     case UINT32:
+                    case FIXED32:
                         num2uint(value);
                         break;
                     case UINT64:
+                    case FIXED64:
                         num2ulong(context.runtime, value);
                         break;
                     default:
@@ -183,14 +191,24 @@
     }
 
     public static IRubyObject wrapPrimaryValue(ThreadContext context, FieldDescriptor.Type fieldType, Object value) {
+        return wrapPrimaryValue(context, fieldType, value, false);
+    }
+
+    public static IRubyObject wrapPrimaryValue(ThreadContext context, FieldDescriptor.Type fieldType, Object value, boolean encodeBytes) {
         Ruby runtime = context.runtime;
         switch (fieldType) {
             case INT32:
+            case SFIXED32:
+            case SINT32:
                 return runtime.newFixnum((Integer) value);
+            case SFIXED64:
+            case SINT64:
             case INT64:
                 return runtime.newFixnum((Long) value);
+            case FIXED32:
             case UINT32:
                 return runtime.newFixnum(((Integer) value) & (-1l >>> 32));
+            case FIXED64:
             case UINT64:
                 long ret = (Long) value;
                 return ret >= 0 ? runtime.newFixnum(ret) :
@@ -202,7 +220,9 @@
             case BOOL:
                 return (Boolean) value ? runtime.getTrue() : runtime.getFalse();
             case BYTES: {
-                IRubyObject wrapped = RubyString.newString(runtime, ((ByteString) value).toStringUtf8(), ASCIIEncoding.INSTANCE);
+                IRubyObject wrapped = encodeBytes ?
+                    RubyString.newString(runtime, ((ByteString) value).toStringUtf8(), ASCIIEncoding.INSTANCE) :
+                    RubyString.newString(runtime, ((ByteString) value).toByteArray());
                 wrapped.setFrozen(true);
                 return wrapped;
             }
@@ -260,58 +280,6 @@
                 fieldDescriptor.getMessageType().getOptions().getMapEntry();
     }
 
-    /*
-     * call-seq:
-     *     Utils.createFieldBuilder(context, label, name, type, number, typeClass = nil, options = nil)
-     *
-     * Most places calling this are already dealing with an optional number of
-     * arguments so dealing with them here. This helper is a standard way to
-     * create a FieldDescriptor builder that handles some of the options that
-     * are used in different places.
-     */
-    public static FieldDescriptorProto.Builder createFieldBuilder(ThreadContext context,
-            String label, IRubyObject[] args) {
-
-        Ruby runtime = context.runtime;
-        IRubyObject options = context.nil;
-        IRubyObject typeClass = context.nil;
-
-        if (args.length > 4) {
-            options = args[4];
-            typeClass = args[3];
-        } else if (args.length > 3) {
-            if (args[3] instanceof RubyHash) {
-                options = args[3];
-            } else {
-                typeClass = args[3];
-            }
-        }
-
-        FieldDescriptorProto.Builder builder = FieldDescriptorProto.newBuilder();
-
-        builder.setLabel(FieldDescriptorProto.Label.valueOf("LABEL_" + label.toUpperCase()))
-            .setName(args[0].asJavaString())
-            .setNumber(RubyNumeric.num2int(args[2]))
-            .setType(FieldDescriptorProto.Type.valueOf("TYPE_" + args[1].asJavaString().toUpperCase()));
-
-        if (!typeClass.isNil()) {
-            if (!(typeClass instanceof RubyString)) {
-                throw runtime.newArgumentError("expected string for type class");
-            }
-            builder.setTypeName("." + typeClass.asJavaString());
-        }
-
-        if (options instanceof RubyHash) {
-            IRubyObject defaultValue = ((RubyHash) options).fastARef(runtime.newSymbol("default"));
-            if (defaultValue != null) {
-                builder.setDefaultValue(defaultValue.toString());
-            }
-        }
-
-        return builder;
-    }
-
-
     public static RaiseException createTypeError(ThreadContext context, String message) {
         if (cTypeError == null) {
             cTypeError = (RubyClass) context.runtime.getClassFromPath("Google::Protobuf::TypeError");
diff --git a/ruby/src/main/java/google/ProtobufJavaService.java b/ruby/src/main/java/google/ProtobufJavaService.java
index a364719..713891e 100644
--- a/ruby/src/main/java/google/ProtobufJavaService.java
+++ b/ruby/src/main/java/google/ProtobufJavaService.java
@@ -49,18 +49,13 @@
          * need to exist before we try to save a reference to them
          */
         RubyProtobuf.createProtobuf(ruby);
-        RubyBuilder.createRubyBuilder(ruby);
         RubyFileDescriptor.createRubyFileDescriptor(ruby);
         RubyEnumDescriptor.createRubyEnumDescriptor(ruby);
-        RubyEnumBuilderContext.createRubyEnumBuilderContext(ruby);
         RubyRepeatedField.createRubyRepeatedField(ruby);
         RubyFieldDescriptor.createRubyFieldDescriptor(ruby);
         RubyMap.createRubyMap(ruby);
         RubyOneofDescriptor.createRubyOneofDescriptor(ruby);
-        RubyOneofBuilderContext.createRubyOneofBuilderContext(ruby);
-        RubyMessageBuilderContext.createRubyMessageBuilderContext(ruby);
         RubyDescriptor.createRubyDescriptor(ruby);
-        RubyFileBuilderContext.createRubyFileBuilderContext(ruby);
         RubyDescriptorPool.createRubyDescriptorPool(ruby);
         return true;
     }
diff --git a/ruby/tests/basic.rb b/ruby/tests/basic.rb
index 6beb4b7..2a7a251 100755
--- a/ruby/tests/basic.rb
+++ b/ruby/tests/basic.rb
@@ -66,7 +66,8 @@
     def test_issue_8559_crash
       msg = TestMessage.new
       msg.repeated_int32 = ::Google::Protobuf::RepeatedField.new(:int32, [1, 2, 3])
-      GC.start(full_mark: true, immediate_sweep: true)
+      # TODO: Remove the platform check once https://github.com/jruby/jruby/issues/6818 is released in JRuby 9.3.0.0
+      GC.start(full_mark: true, immediate_sweep: true) unless RUBY_PLATFORM == "java"
       TestMessage.encode(msg)
     end
 
@@ -168,6 +169,17 @@
       assert_equal nil, m.singular_msg
     end
 
+    def test_import_proto2
+      m = TestMessage.new
+      assert !m.has_optional_proto2_submessage?
+      m.optional_proto2_submessage = ::FooBar::Proto2::TestImportedMessage.new
+      assert m.has_optional_proto2_submessage?
+      assert TestMessage.descriptor.lookup('optional_proto2_submessage').has?(m)
+
+      m.clear_optional_proto2_submessage
+      assert !m.has_optional_proto2_submessage?
+    end
+
     def test_clear_repeated_fields
       m = TestMessage.new
 
@@ -487,6 +499,7 @@
         :optional_int64=>0,
         :optional_msg=>nil,
         :optional_msg2=>nil,
+        :optional_proto2_submessage=>nil,
         :optional_string=>"foo",
         :optional_uint32=>0,
         :optional_uint64=>0,
diff --git a/ruby/tests/basic_test.proto b/ruby/tests/basic_test.proto
index 5b4ed63..bca172a 100644
--- a/ruby/tests/basic_test.proto
+++ b/ruby/tests/basic_test.proto
@@ -6,6 +6,7 @@
 import "google/protobuf/timestamp.proto";
 import "google/protobuf/duration.proto";
 import "google/protobuf/struct.proto";
+import "test_import_proto2.proto";
 
 message Foo {
   Bar bar = 1;
@@ -32,6 +33,7 @@
   optional bytes optional_bytes = 9;
   optional TestMessage2 optional_msg = 10;
   optional TestEnum optional_enum = 11;
+  optional foo_bar.proto2.TestImportedMessage optional_proto2_submessage = 24;
 
   repeated int32 repeated_int32 = 12;
   repeated int64 repeated_int64 = 13;
@@ -208,3 +210,8 @@
   string string = 1;
   google.protobuf.Struct struct = 2;
 }
+
+message WithJsonName {
+  optional int32 foo_bar = 1 [json_name="jsonFooBar"];
+  repeated WithJsonName baz = 2 [json_name="jsonBaz"];
+}
diff --git a/ruby/tests/common_tests.rb b/ruby/tests/common_tests.rb
index 7021d60..3d9f67e 100644
--- a/ruby/tests/common_tests.rb
+++ b/ruby/tests/common_tests.rb
@@ -1781,21 +1781,24 @@
   def test_object_gc
     m = proto_module::TestMessage.new(optional_msg: proto_module::TestMessage2.new)
     m.optional_msg
-    GC.start(full_mark: true, immediate_sweep: true)
+    # TODO: Remove the platform check once https://github.com/jruby/jruby/issues/6818 is released in JRuby 9.3.0.0
+    GC.start(full_mark: true, immediate_sweep: true) unless RUBY_PLATFORM == "java"
     m.optional_msg.inspect
   end
 
   def test_object_gc_freeze
     m = proto_module::TestMessage.new
     m.repeated_float.freeze
-    GC.start(full_mark: true)
+    # TODO: Remove the platform check once https://github.com/jruby/jruby/issues/6818 is released in JRuby 9.3.0.0
+    GC.start(full_mark: true) unless RUBY_PLATFORM == "java"
 
     # Make sure we remember that the object is frozen.
     # The wrapper object contains this information, so we need to ensure that
     # the previous GC did not collect it.
     assert m.repeated_float.frozen?
 
-    GC.start(full_mark: true, immediate_sweep: true)
+    # TODO: Remove the platform check once https://github.com/jruby/jruby/issues/6818 is released in JRuby 9.3.0.0
+    GC.start(full_mark: true, immediate_sweep: true) unless RUBY_PLATFORM == "java"
     assert m.repeated_float.frozen?
   end
 end
diff --git a/ruby/tests/stress.rb b/ruby/tests/stress.rb
index 082d5e2..6a3f51d 100755
--- a/ruby/tests/stress.rb
+++ b/ruby/tests/stress.rb
@@ -30,7 +30,7 @@
       100_000.times do
         mnew = TestMessage.decode(data)
         mnew = mnew.dup
-        assert_equal mnew.inspect, m.inspect
+        assert_equal m.inspect, mnew.inspect
         assert TestMessage.encode(mnew) == data
       end
     end
diff --git a/ruby/travis-test.sh b/ruby/travis-test.sh
index 8980395..edca986 100755
--- a/ruby/travis-test.sh
+++ b/ruby/travis-test.sh
@@ -1,7 +1,7 @@
 #!/usr/bin/env bash
 
 # Exit on any error.
-set -e
+set -ex
 
 test_version() {
   version=$1
@@ -13,35 +13,22 @@
       "rvm install $version && rvm use $version && rvm get head && \
        which ruby && \
        git clean -f && \
-       gem install bundler && bundle && \
-       rake test &&
-       rake gc_test &&
-       cd ../conformance && make test_jruby &&
+       gem install --no-document bundler && bundle && \
+       rake test && \
+       rake gc_test && \
+       cd ../conformance && make test_jruby && \
        cd ../ruby/compatibility_tests/v3.0.0 && ./test.sh"
-  elif [ "$version" == "ruby-2.6.0" -o "$version" == "ruby-2.7.0" -o "$version" == "ruby-3.0.2" ] ; then
+  else
     bash --login -c \
       "rvm install $version && rvm use $version && \
        which ruby && \
        git clean -f && \
-       gem install bundler -v 1.17.3 && bundle && \
-       rake test &&
-       rake gc_test &&
-       cd ../conformance && make ${RUBY_CONFORMANCE} &&
-       cd ../ruby/compatibility_tests/v3.0.0 &&
+       gem install --no-document bundler -v 1.17.3 && bundle && \
+       rake test && \
+       rake gc_test && \
+       cd ../conformance && make ${RUBY_CONFORMANCE} && \
+       cd ../ruby/compatibility_tests/v3.0.0 && \
        cp -R ../../lib lib && ./test.sh"
-  else
-    # Recent versions of OSX have deprecated OpenSSL, so we have to explicitly
-    # provide a path to the OpenSSL directory installed via Homebrew.
-    bash --login -c \
-      "rvm install $version --with-openssl-dir=`brew --prefix openssl` && \
-       rvm use $version && \
-       which ruby && \
-       git clean -f && \
-       gem install bundler -v 1.17.3 && bundle && \
-       rake test &&
-       rake gc_test &&
-       cd ../conformance && make ${RUBY_CONFORMANCE} &&
-       cd ../ruby/compatibility_tests/v3.0.0 && ./test.sh"
   fi
 }
 
diff --git a/src/Makefile.am b/src/Makefile.am
index b1cdd5a..ce65d79 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -18,7 +18,7 @@
 PTHREAD_DEF =
 endif
 
-PROTOBUF_VERSION = 28:3:0
+PROTOBUF_VERSION = 29:0:0
 
 if GCC
 # Turn on all warnings except for sign comparison (we ignore sign comparison
@@ -100,6 +100,7 @@
   google/protobuf/duration.pb.h                                  \
   google/protobuf/dynamic_message.h                              \
   google/protobuf/empty.pb.h                                     \
+  google/protobuf/explicitly_constructed.h                       \
   google/protobuf/extension_set.h                                \
   google/protobuf/extension_set_inl.h                            \
   google/protobuf/field_access_listener.h                        \
@@ -540,6 +541,7 @@
   google/protobuf/compiler/package_info.h                      \
   google/protobuf/compiler/ruby/ruby_generated_code.proto      \
   google/protobuf/compiler/ruby/ruby_generated_code_pb.rb      \
+  google/protobuf/compiler/ruby/ruby_generated_code_proto2_import.proto         \
   google/protobuf/compiler/ruby/ruby_generated_code_proto2.proto \
   google/protobuf/compiler/ruby/ruby_generated_code_proto2_pb.rb \
   google/protobuf/compiler/ruby/ruby_generated_pkg_explicit.proto \
diff --git a/src/google/protobuf/any.pb.h b/src/google/protobuf/any.pb.h
index f601913..46c90bd 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 < 3017000
+#if PROTOBUF_VERSION < 3018000
 #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 3017003 < PROTOBUF_MIN_PROTOC_VERSION
+#if 3018000 < 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.
@@ -172,11 +172,7 @@
 
   // implements Message ----------------------------------------------
 
-  inline Any* New() const final {
-    return new Any();
-  }
-
-  Any* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final {
+  Any* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final {
     return CreateMaybeMessage<Any>(arena);
   }
   using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom;
@@ -200,6 +196,8 @@
   void SharedDtor();
   void SetCachedSize(int size) const final;
   void InternalSwap(Any* other);
+
+  private:
   friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
   static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
     return "google.protobuf.Any";
@@ -231,7 +229,7 @@
   template <typename ArgT0 = const std::string&, typename... ArgT>
   void set_type_url(ArgT0&& arg0, ArgT... args);
   std::string* mutable_type_url();
-  PROTOBUF_MUST_USE_RESULT std::string* release_type_url();
+  PROTOBUF_NODISCARD std::string* release_type_url();
   void set_allocated_type_url(std::string* type_url);
   private:
   const std::string& _internal_type_url() const;
@@ -245,7 +243,7 @@
   template <typename ArgT0 = const std::string&, typename... ArgT>
   void set_value(ArgT0&& arg0, ArgT... args);
   std::string* mutable_value();
-  PROTOBUF_MUST_USE_RESULT std::string* release_value();
+  PROTOBUF_NODISCARD std::string* release_value();
   void set_allocated_value(std::string* value);
   private:
   const std::string& _internal_value() const;
diff --git a/src/google/protobuf/api.pb.h b/src/google/protobuf/api.pb.h
index 4ed460e..84de2cd 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 < 3017000
+#if PROTOBUF_VERSION < 3018000
 #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 3017003 < PROTOBUF_MIN_PROTOC_VERSION
+#if 3018000 < 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.
@@ -149,11 +149,7 @@
 
   // implements Message ----------------------------------------------
 
-  inline Api* New() const final {
-    return new Api();
-  }
-
-  Api* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final {
+  Api* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final {
     return CreateMaybeMessage<Api>(arena);
   }
   using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom;
@@ -177,6 +173,8 @@
   void SharedDtor();
   void SetCachedSize(int size) const final;
   void InternalSwap(Api* other);
+
+  private:
   friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
   static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
     return "google.protobuf.Api";
@@ -267,7 +265,7 @@
   template <typename ArgT0 = const std::string&, typename... ArgT>
   void set_name(ArgT0&& arg0, ArgT... args);
   std::string* mutable_name();
-  PROTOBUF_MUST_USE_RESULT std::string* release_name();
+  PROTOBUF_NODISCARD std::string* release_name();
   void set_allocated_name(std::string* name);
   private:
   const std::string& _internal_name() const;
@@ -281,7 +279,7 @@
   template <typename ArgT0 = const std::string&, typename... ArgT>
   void set_version(ArgT0&& arg0, ArgT... args);
   std::string* mutable_version();
-  PROTOBUF_MUST_USE_RESULT std::string* release_version();
+  PROTOBUF_NODISCARD std::string* release_version();
   void set_allocated_version(std::string* version);
   private:
   const std::string& _internal_version() const;
@@ -296,7 +294,7 @@
   public:
   void clear_source_context();
   const ::PROTOBUF_NAMESPACE_ID::SourceContext& source_context() const;
-  PROTOBUF_MUST_USE_RESULT ::PROTOBUF_NAMESPACE_ID::SourceContext* release_source_context();
+  PROTOBUF_NODISCARD ::PROTOBUF_NAMESPACE_ID::SourceContext* release_source_context();
   ::PROTOBUF_NAMESPACE_ID::SourceContext* mutable_source_context();
   void set_allocated_source_context(::PROTOBUF_NAMESPACE_ID::SourceContext* source_context);
   private:
@@ -409,11 +407,7 @@
 
   // implements Message ----------------------------------------------
 
-  inline Method* New() const final {
-    return new Method();
-  }
-
-  Method* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final {
+  Method* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final {
     return CreateMaybeMessage<Method>(arena);
   }
   using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom;
@@ -437,6 +431,8 @@
   void SharedDtor();
   void SetCachedSize(int size) const final;
   void InternalSwap(Method* other);
+
+  private:
   friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
   static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
     return "google.protobuf.Method";
@@ -491,7 +487,7 @@
   template <typename ArgT0 = const std::string&, typename... ArgT>
   void set_name(ArgT0&& arg0, ArgT... args);
   std::string* mutable_name();
-  PROTOBUF_MUST_USE_RESULT std::string* release_name();
+  PROTOBUF_NODISCARD std::string* release_name();
   void set_allocated_name(std::string* name);
   private:
   const std::string& _internal_name() const;
@@ -505,7 +501,7 @@
   template <typename ArgT0 = const std::string&, typename... ArgT>
   void set_request_type_url(ArgT0&& arg0, ArgT... args);
   std::string* mutable_request_type_url();
-  PROTOBUF_MUST_USE_RESULT std::string* release_request_type_url();
+  PROTOBUF_NODISCARD std::string* release_request_type_url();
   void set_allocated_request_type_url(std::string* request_type_url);
   private:
   const std::string& _internal_request_type_url() const;
@@ -519,7 +515,7 @@
   template <typename ArgT0 = const std::string&, typename... ArgT>
   void set_response_type_url(ArgT0&& arg0, ArgT... args);
   std::string* mutable_response_type_url();
-  PROTOBUF_MUST_USE_RESULT std::string* release_response_type_url();
+  PROTOBUF_NODISCARD std::string* release_response_type_url();
   void set_allocated_response_type_url(std::string* response_type_url);
   private:
   const std::string& _internal_response_type_url() const;
@@ -647,11 +643,7 @@
 
   // implements Message ----------------------------------------------
 
-  inline Mixin* New() const final {
-    return new Mixin();
-  }
-
-  Mixin* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final {
+  Mixin* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final {
     return CreateMaybeMessage<Mixin>(arena);
   }
   using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom;
@@ -675,6 +667,8 @@
   void SharedDtor();
   void SetCachedSize(int size) const final;
   void InternalSwap(Mixin* other);
+
+  private:
   friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
   static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
     return "google.protobuf.Mixin";
@@ -706,7 +700,7 @@
   template <typename ArgT0 = const std::string&, typename... ArgT>
   void set_name(ArgT0&& arg0, ArgT... args);
   std::string* mutable_name();
-  PROTOBUF_MUST_USE_RESULT std::string* release_name();
+  PROTOBUF_NODISCARD std::string* release_name();
   void set_allocated_name(std::string* name);
   private:
   const std::string& _internal_name() const;
@@ -720,7 +714,7 @@
   template <typename ArgT0 = const std::string&, typename... ArgT>
   void set_root(ArgT0&& arg0, ArgT... args);
   std::string* mutable_root();
-  PROTOBUF_MUST_USE_RESULT std::string* release_root();
+  PROTOBUF_NODISCARD std::string* release_root();
   void set_allocated_root(std::string* root);
   private:
   const std::string& _internal_root() const;
diff --git a/src/google/protobuf/arena.cc b/src/google/protobuf/arena.cc
index c12bf2b..7624e0b 100644
--- a/src/google/protobuf/arena.cc
+++ b/src/google/protobuf/arena.cc
@@ -216,31 +216,54 @@
 
 void ThreadSafeArena::InitializeFrom(void* mem, size_t size) {
   GOOGLE_DCHECK_EQ(reinterpret_cast<uintptr_t>(mem) & 7, 0u);
-  Init(false);
+  GOOGLE_DCHECK(!AllocPolicy());  // Reset should call InitializeWithPolicy instead.
+  Init();
 
   // Ignore initial block if it is too small.
   if (mem != nullptr && size >= kBlockHeaderSize + kSerialArenaSize) {
-    alloc_policy_ |= kUserOwnedInitialBlock;
+    alloc_policy_.set_is_user_owned_initial_block(true);
     SetInitialBlock(mem, size);
   }
 }
 
 void ThreadSafeArena::InitializeWithPolicy(void* mem, size_t size,
-                                           bool record_allocs,
                                            AllocationPolicy policy) {
-  GOOGLE_DCHECK_EQ(reinterpret_cast<uintptr_t>(mem) & 7, 0u);
+#ifndef NDEBUG
+  const uint64_t old_alloc_policy = alloc_policy_.get_raw();
+  // If there was a policy (e.g., in Reset()), make sure flags were preserved.
+#define GOOGLE_DCHECK_POLICY_FLAGS_() \
+  if (old_alloc_policy > 3)    \
+    GOOGLE_CHECK_EQ(old_alloc_policy & 3, alloc_policy_.get_raw() & 3)
+#else
+#define GOOGLE_DCHECK_POLICY_FLAGS_()
+#endif  // NDEBUG
 
-  Init(record_allocs);
+  if (policy.IsDefault()) {
+    // Legacy code doesn't use the API above, but provides the initial block
+    // through ArenaOptions. I suspect most do not touch the allocation
+    // policy parameters.
+    InitializeFrom(mem, size);
+    GOOGLE_DCHECK_POLICY_FLAGS_();
+    return;
+  }
+  GOOGLE_DCHECK_EQ(reinterpret_cast<uintptr_t>(mem) & 7, 0u);
+  Init();
 
   // Ignore initial block if it is too small. We include an optional
   // AllocationPolicy in this check, so that this can be allocated on the
   // first block.
   constexpr size_t kAPSize = internal::AlignUpTo8(sizeof(AllocationPolicy));
   constexpr size_t kMinimumSize = kBlockHeaderSize + kSerialArenaSize + kAPSize;
+
+  // The value for alloc_policy_ stores whether or not allocations should be
+  // recorded.
+  alloc_policy_.set_should_record_allocs(
+      policy.metrics_collector != nullptr &&
+      policy.metrics_collector->RecordAllocs());
+  // Make sure we have an initial block to store the AllocationPolicy.
   if (mem != nullptr && size >= kMinimumSize) {
-    alloc_policy_ = kUserOwnedInitialBlock;
+    alloc_policy_.set_is_user_owned_initial_block(true);
   } else {
-    alloc_policy_ = 0;
     auto tmp = AllocateMemory(&policy, 0, kMinimumSize);
     mem = tmp.ptr;
     size = tmp.size;
@@ -255,10 +278,18 @@
     return;
   }
   new (p) AllocationPolicy{policy};
-  alloc_policy_ |= reinterpret_cast<intptr_t>(p);
+  // Low bits store flags, so they mustn't be overwritten.
+  GOOGLE_DCHECK_EQ(0, reinterpret_cast<uintptr_t>(p) & 3);
+  alloc_policy_.set_policy(reinterpret_cast<AllocationPolicy*>(p));
+  GOOGLE_DCHECK_POLICY_FLAGS_();
+
+#undef GOOGLE_DCHECK_POLICY_FLAGS_
 }
 
-void ThreadSafeArena::Init(bool record_allocs) {
+void ThreadSafeArena::Init() {
+#ifndef NDEBUG
+  const bool was_message_owned = IsMessageOwned();
+#endif  // NDEBUG
   ThreadCache& tc = thread_cache();
   auto id = tc.next_lifecycle_id;
   // We increment lifecycle_id's by multiples of two so we can use bit 0 as
@@ -273,9 +304,14 @@
     id = lifecycle_id_generator_.id.fetch_add(1, relaxed) * kInc;
   }
   tc.next_lifecycle_id = id + kDelta;
-  tag_and_id_ = id | (record_allocs ? kRecordAllocs : 0);
+  // Message ownership is stored in tag_and_id_, and is set in the constructor.
+  // This flag bit must be preserved, even across calls to Reset().
+  tag_and_id_ = id | (tag_and_id_ & kMessageOwnedArena);
   hint_.store(nullptr, std::memory_order_relaxed);
   threads_.store(nullptr, std::memory_order_relaxed);
+#ifndef NDEBUG
+  GOOGLE_CHECK_EQ(was_message_owned, IsMessageOwned());
+#endif  // NDEBUG
 }
 
 void ThreadSafeArena::SetInitialBlock(void* mem, size_t size) {
@@ -294,13 +330,13 @@
   auto mem = Free(&space_allocated);
 
   // Policy is about to get deleted.
-  auto p = AllocPolicy();
+  auto* p = alloc_policy_.get();
   ArenaMetricsCollector* collector = p ? p->metrics_collector : nullptr;
 
-  if (alloc_policy_ & kUserOwnedInitialBlock) {
+  if (alloc_policy_.is_user_owned_initial_block()) {
     space_allocated += mem.size;
   } else {
-    GetDeallocator(AllocPolicy(), &space_allocated)(mem);
+    GetDeallocator(alloc_policy_.get(), &space_allocated)(mem);
   }
 
   if (collector) collector->OnDestroy(space_allocated);
@@ -308,7 +344,7 @@
 
 SerialArena::Memory ThreadSafeArena::Free(size_t* space_allocated) {
   SerialArena::Memory mem = {nullptr, 0};
-  auto deallocator = GetDeallocator(AllocPolicy(), space_allocated);
+  auto deallocator = GetDeallocator(alloc_policy_.get(), space_allocated);
   PerSerialArena([deallocator, &mem](SerialArena* a) {
     if (mem.ptr) deallocator(mem);
     mem = a->Free(deallocator);
@@ -325,26 +361,28 @@
   size_t space_allocated = 0;
   auto mem = Free(&space_allocated);
 
-  if (AllocPolicy()) {
-    auto saved_policy = *AllocPolicy();
-    if (alloc_policy_ & kUserOwnedInitialBlock) {
+  AllocationPolicy* policy = alloc_policy_.get();
+  if (policy) {
+    auto saved_policy = *policy;
+    if (alloc_policy_.is_user_owned_initial_block()) {
       space_allocated += mem.size;
     } else {
-      GetDeallocator(AllocPolicy(), &space_allocated)(mem);
+      GetDeallocator(alloc_policy_.get(), &space_allocated)(mem);
       mem.ptr = nullptr;
       mem.size = 0;
     }
     ArenaMetricsCollector* collector = saved_policy.metrics_collector;
     if (collector) collector->OnReset(space_allocated);
-    InitializeWithPolicy(mem.ptr, mem.size, ShouldRecordAlloc(), saved_policy);
+    InitializeWithPolicy(mem.ptr, mem.size, saved_policy);
   } else {
+    GOOGLE_DCHECK(!alloc_policy_.should_record_allocs());
     // Nullptr policy
-    if (alloc_policy_ & kUserOwnedInitialBlock) {
+    if (alloc_policy_.is_user_owned_initial_block()) {
       space_allocated += mem.size;
       InitializeFrom(mem.ptr, mem.size);
     } else {
-      GetDeallocator(AllocPolicy(), &space_allocated)(mem);
-      Init(false);
+      GetDeallocator(alloc_policy_.get(), &space_allocated)(mem);
+      Init();
     }
   }
 
@@ -355,8 +393,9 @@
 ThreadSafeArena::AllocateAlignedWithCleanup(size_t n,
                                             const std::type_info* type) {
   SerialArena* arena;
-  if (PROTOBUF_PREDICT_TRUE(GetSerialArenaFast(tag_and_id_, &arena))) {
-    return arena->AllocateAlignedWithCleanup(n, AllocPolicy());
+  if (PROTOBUF_PREDICT_TRUE(!alloc_policy_.should_record_allocs() &&
+                            GetSerialArenaFast(&arena))) {
+    return arena->AllocateAlignedWithCleanup(n, alloc_policy_.get());
   } else {
     return AllocateAlignedWithCleanupFallback(n, type);
   }
@@ -364,46 +403,39 @@
 
 void ThreadSafeArena::AddCleanup(void* elem, void (*cleanup)(void*)) {
   SerialArena* arena;
-  if (PROTOBUF_PREDICT_TRUE(GetSerialArenaFast(LifeCycleId(), &arena))) {
-    arena->AddCleanup(elem, cleanup, AllocPolicy());
-  } else {
-    return AddCleanupFallback(elem, cleanup);
+  if (PROTOBUF_PREDICT_FALSE(!GetSerialArenaFast(&arena))) {
+    arena = GetSerialArenaFallback(&thread_cache());
   }
+  arena->AddCleanup(elem, cleanup, AllocPolicy());
 }
 
 PROTOBUF_NOINLINE
 void* ThreadSafeArena::AllocateAlignedFallback(size_t n,
                                                const std::type_info* type) {
-  if (ShouldRecordAlloc()) {
-    RecordAlloc(type, n);
+  if (alloc_policy_.should_record_allocs()) {
+    alloc_policy_.RecordAlloc(type, n);
     SerialArena* arena;
-    if (PROTOBUF_PREDICT_TRUE(GetSerialArenaFast(LifeCycleId(), &arena))) {
-      return arena->AllocateAligned(n, AllocPolicy());
+    if (PROTOBUF_PREDICT_TRUE(GetSerialArenaFast(&arena))) {
+      return arena->AllocateAligned(n, alloc_policy_.get());
     }
   }
   return GetSerialArenaFallback(&thread_cache())
-      ->AllocateAligned(n, AllocPolicy());
+      ->AllocateAligned(n, alloc_policy_.get());
 }
 
 PROTOBUF_NOINLINE
 std::pair<void*, SerialArena::CleanupNode*>
 ThreadSafeArena::AllocateAlignedWithCleanupFallback(
     size_t n, const std::type_info* type) {
-  if (ShouldRecordAlloc()) {
-    RecordAlloc(type, n);
+  if (alloc_policy_.should_record_allocs()) {
+    alloc_policy_.RecordAlloc(type, n);
     SerialArena* arena;
-    if (GetSerialArenaFast(LifeCycleId(), &arena)) {
-      return arena->AllocateAlignedWithCleanup(n, AllocPolicy());
+    if (GetSerialArenaFast(&arena)) {
+      return arena->AllocateAlignedWithCleanup(n, alloc_policy_.get());
     }
   }
   return GetSerialArenaFallback(&thread_cache())
-      ->AllocateAlignedWithCleanup(n, AllocPolicy());
-}
-
-PROTOBUF_NOINLINE
-void ThreadSafeArena::AddCleanupFallback(void* elem, void (*cleanup)(void*)) {
-  GetSerialArenaFallback(&thread_cache())
-      ->AddCleanup(elem, cleanup, AllocPolicy());
+      ->AllocateAlignedWithCleanup(n, alloc_policy_.get());
 }
 
 uint64_t ThreadSafeArena::SpaceAllocated() const {
@@ -421,7 +453,7 @@
   for (; serial; serial = serial->next()) {
     space_used += serial->SpaceUsed();
   }
-  return space_used - (AllocPolicy() ? sizeof(AllocationPolicy) : 0);
+  return space_used - (alloc_policy_.get() ? sizeof(AllocationPolicy) : 0);
 }
 
 void ThreadSafeArena::CleanupList() {
@@ -442,7 +474,7 @@
     // This thread doesn't have any SerialArena, which also means it doesn't
     // have any blocks yet.  So we'll allocate its first block now.
     serial = SerialArena::New(
-        AllocateMemory(AllocPolicy(), 0, kSerialArenaSize), me);
+        AllocateMemory(alloc_policy_.get(), 0, kSerialArenaSize), me);
 
     SerialArena* head = threads_.load(std::memory_order_relaxed);
     do {
diff --git a/src/google/protobuf/arena.h b/src/google/protobuf/arena.h
index 54a7650..6dd6467 100644
--- a/src/google/protobuf/arena.h
+++ b/src/google/protobuf/arena.h
@@ -65,13 +65,6 @@
 namespace protobuf {
 
 struct ArenaOptions;  // defined below
-
-}  // namespace protobuf
-}  // namespace google
-
-namespace google {
-namespace protobuf {
-
 class Arena;    // defined below
 class Message;  // defined in message.h
 class MessageLite;
diff --git a/src/google/protobuf/arena_impl.h b/src/google/protobuf/arena_impl.h
index 302d4cd..d38e311 100644
--- a/src/google/protobuf/arena_impl.h
+++ b/src/google/protobuf/arena_impl.h
@@ -108,6 +108,75 @@
   }
 };
 
+// Tagged pointer to an AllocationPolicy.
+class TaggedAllocationPolicyPtr {
+ public:
+  constexpr TaggedAllocationPolicyPtr() : policy_(0) {}
+
+  explicit TaggedAllocationPolicyPtr(AllocationPolicy* policy)
+      : policy_(reinterpret_cast<uintptr_t>(policy)) {}
+
+  void set_policy(AllocationPolicy* policy) {
+    auto bits = policy_ & kTagsMask;
+    policy_ = reinterpret_cast<uintptr_t>(policy) | bits;
+  }
+
+  AllocationPolicy* get() {
+    return reinterpret_cast<AllocationPolicy*>(policy_ & kPtrMask);
+  }
+  const AllocationPolicy* get() const {
+    return reinterpret_cast<const AllocationPolicy*>(policy_ & kPtrMask);
+  }
+
+  AllocationPolicy& operator*() { return *get(); }
+  const AllocationPolicy& operator*() const { return *get(); }
+
+  AllocationPolicy* operator->() { return get(); }
+  const AllocationPolicy* operator->() const { return get(); }
+
+  bool is_user_owned_initial_block() const {
+    return static_cast<bool>(get_mask<kUserOwnedInitialBlock>());
+  }
+  void set_is_user_owned_initial_block(bool v) {
+    set_mask<kUserOwnedInitialBlock>(v);
+  }
+
+  bool should_record_allocs() const {
+    return static_cast<bool>(get_mask<kRecordAllocs>());
+  }
+  void set_should_record_allocs(bool v) { set_mask<kRecordAllocs>(v); }
+
+  uintptr_t get_raw() const { return policy_; }
+
+  inline void RecordAlloc(const std::type_info* allocated_type,
+                          size_t n) const {
+    get()->metrics_collector->OnAlloc(allocated_type, n);
+  }
+
+ private:
+  enum : uintptr_t {
+    kUserOwnedInitialBlock = 1,
+    kRecordAllocs = 2,
+  };
+
+  static constexpr uintptr_t kTagsMask = 7;
+  static constexpr uintptr_t kPtrMask = ~kTagsMask;
+
+  template <uintptr_t kMask>
+  uintptr_t get_mask() const {
+    return policy_ & kMask;
+  }
+  template <uintptr_t kMask>
+  void set_mask(bool v) {
+    if (v) {
+      policy_ |= kMask;
+    } else {
+      policy_ &= ~kMask;
+    }
+  }
+  uintptr_t policy_;
+};
+
 // A simple arena allocator. Calls to allocate functions must be properly
 // serialized by the caller, hence this class cannot be used as a general
 // purpose allocator in a multi-threaded program. It serves as a building block
@@ -179,6 +248,7 @@
 
   std::pair<void*, CleanupNode*> AllocateAlignedWithCleanup(
       size_t n, const AllocationPolicy* policy) {
+    GOOGLE_DCHECK_EQ(internal::AlignUpTo8(n), n);  // Must be already aligned.
     if (PROTOBUF_PREDICT_FALSE(!HasSpace(n + kCleanupSize))) {
       return AllocateAlignedWithCleanupFallback(n, policy);
     }
@@ -270,27 +340,18 @@
 // use #ifdef the select the best implementation based on hardware / OS.
 class PROTOBUF_EXPORT ThreadSafeArena {
  public:
-  ThreadSafeArena() { Init(false); }
+  ThreadSafeArena() { Init(); }
 
   // Constructor solely used by message-owned arena.
-  ThreadSafeArena(internal::MessageOwned) : alloc_policy_(kMessageOwnedArena) {
-    Init(false);
+  ThreadSafeArena(internal::MessageOwned) : tag_and_id_(kMessageOwnedArena) {
+    Init();
   }
 
   ThreadSafeArena(char* mem, size_t size) { InitializeFrom(mem, size); }
 
   explicit ThreadSafeArena(void* mem, size_t size,
                            const AllocationPolicy& policy) {
-    if (policy.IsDefault()) {
-      // Legacy code doesn't use the API above, but provides the initial block
-      // through ArenaOptions. I suspect most do not touch the allocation
-      // policy parameters.
-      InitializeFrom(mem, size);
-    } else {
-      auto collector = policy.metrics_collector;
-      bool record_allocs = collector && collector->RecordAllocs();
-      InitializeWithPolicy(mem, size, record_allocs, policy);
-    }
+    InitializeWithPolicy(mem, size, policy);
   }
 
   // Destructor deletes all owned heap allocated objects, and destructs objects
@@ -306,7 +367,8 @@
 
   void* AllocateAligned(size_t n, const std::type_info* type) {
     SerialArena* arena;
-    if (PROTOBUF_PREDICT_TRUE(GetSerialArenaFast(tag_and_id_, &arena))) {
+    if (PROTOBUF_PREDICT_TRUE(!alloc_policy_.should_record_allocs() &&
+                              GetSerialArenaFast(&arena))) {
       return arena->AllocateAligned(n, AllocPolicy());
     } else {
       return AllocateAlignedFallback(n, type);
@@ -320,7 +382,8 @@
   // code for the happy path.
   PROTOBUF_NDEBUG_INLINE bool MaybeAllocateAligned(size_t n, void** out) {
     SerialArena* a;
-    if (PROTOBUF_PREDICT_TRUE(GetSerialArenaFromThreadCache(tag_and_id_, &a))) {
+    if (PROTOBUF_PREDICT_TRUE(!alloc_policy_.should_record_allocs() &&
+                              GetSerialArenaFromThreadCache(&a))) {
       return a->MaybeAllocateAligned(n, out);
     }
     return false;
@@ -334,58 +397,41 @@
 
   // Checks whether this arena is message-owned.
   PROTOBUF_ALWAYS_INLINE bool IsMessageOwned() const {
-    return alloc_policy_ & kMessageOwnedArena;
+    return tag_and_id_ & kMessageOwnedArena;
   }
 
  private:
   // Unique for each arena. Changes on Reset().
-  uint64_t tag_and_id_;
-  // The LSB of tag_and_id_ indicates if allocs in this arena are recorded.
-  enum { kRecordAllocs = 1 };
+  uint64_t tag_and_id_ = 0;
+  // The LSB of tag_and_id_ indicates if the arena is message-owned.
+  enum : uint64_t { kMessageOwnedArena = 1 };
 
-  intptr_t alloc_policy_ = 0;  // Tagged pointer to AllocPolicy.
-  // The LSB of alloc_policy_ indicates if the user owns the initial block.
-  // The second LSB of alloc_policy_ indicates if the arena is message-owned.
-  enum {
-    kUserOwnedInitialBlock = 1,
-    kMessageOwnedArena = 2,
-  };
+  TaggedAllocationPolicyPtr alloc_policy_;  // Tagged pointer to AllocPolicy.
 
   // Pointer to a linked list of SerialArena.
   std::atomic<SerialArena*> threads_;
   std::atomic<SerialArena*> hint_;  // Fast thread-local block access
 
-  const AllocationPolicy* AllocPolicy() const {
-    return reinterpret_cast<const AllocationPolicy*>(alloc_policy_ & -8);
-  }
+  const AllocationPolicy* AllocPolicy() const { return alloc_policy_.get(); }
   void InitializeFrom(void* mem, size_t size);
-  void InitializeWithPolicy(void* mem, size_t size, bool record_allocs,
-                            AllocationPolicy policy);
+  void InitializeWithPolicy(void* mem, size_t size, AllocationPolicy policy);
   void* AllocateAlignedFallback(size_t n, const std::type_info* type);
   std::pair<void*, SerialArena::CleanupNode*>
   AllocateAlignedWithCleanupFallback(size_t n, const std::type_info* type);
-  void AddCleanupFallback(void* elem, void (*cleanup)(void*));
 
-  void Init(bool record_allocs);
+  void Init();
   void SetInitialBlock(void* mem, size_t size);
 
   // Delete or Destruct all objects owned by the arena.
   void CleanupList();
 
-  inline bool ShouldRecordAlloc() const { return tag_and_id_ & kRecordAllocs; }
-
   inline uint64_t LifeCycleId() const {
-    return tag_and_id_ & (-kRecordAllocs - 1);
-  }
-
-  inline void RecordAlloc(const std::type_info* allocated_type,
-                          size_t n) const {
-    AllocPolicy()->metrics_collector->OnAlloc(allocated_type, n);
+    return tag_and_id_ & ~kMessageOwnedArena;
   }
 
   inline void CacheSerialArena(SerialArena* serial) {
     thread_cache().last_serial_arena = serial;
-    thread_cache().last_lifecycle_id_seen = LifeCycleId();
+    thread_cache().last_lifecycle_id_seen = tag_and_id_;
     // TODO(haberman): evaluate whether we would gain efficiency by getting rid
     // of hint_.  It's the only write we do to ThreadSafeArena in the allocation
     // path, which will dirty the cache line.
@@ -393,10 +439,8 @@
     hint_.store(serial, std::memory_order_release);
   }
 
-  PROTOBUF_NDEBUG_INLINE bool GetSerialArenaFast(uint64_t lifecycle_id,
-                                                 SerialArena** arena) {
-    if (GetSerialArenaFromThreadCache(lifecycle_id, arena)) return true;
-    if (lifecycle_id & kRecordAllocs) return false;
+  PROTOBUF_NDEBUG_INLINE bool GetSerialArenaFast(SerialArena** arena) {
+    if (GetSerialArenaFromThreadCache(arena)) return true;
 
     // Check whether we own the last accessed SerialArena on this arena.  This
     // fast path optimizes the case where a single thread uses multiple arenas.
@@ -410,12 +454,12 @@
   }
 
   PROTOBUF_NDEBUG_INLINE bool GetSerialArenaFromThreadCache(
-      uint64_t lifecycle_id, SerialArena** arena) {
+      SerialArena** arena) {
     // If this thread already owns a block in this arena then try to use that.
     // This fast path optimizes the case where multiple threads allocate from
     // the same arena.
     ThreadCache* tc = &thread_cache();
-    if (PROTOBUF_PREDICT_TRUE(tc->last_lifecycle_id_seen == lifecycle_id)) {
+    if (PROTOBUF_PREDICT_TRUE(tc->last_lifecycle_id_seen == tag_and_id_)) {
       *arena = tc->last_serial_arena;
       return true;
     }
diff --git a/src/google/protobuf/arenastring.h b/src/google/protobuf/arenastring.h
index df11af6..38c3637 100644
--- a/src/google/protobuf/arenastring.h
+++ b/src/google/protobuf/arenastring.h
@@ -243,9 +243,9 @@
   // Own()'d by any arena. If the field is not set, this returns nullptr. The
   // caller retains ownership. Clears this field back to nullptr state. Used to
   // implement release_<field>() methods on generated classes.
-  PROTOBUF_MUST_USE_RESULT std::string* Release(
-      const std::string* default_value, ::google::protobuf::Arena* arena);
-  PROTOBUF_MUST_USE_RESULT std::string* ReleaseNonDefault(
+  PROTOBUF_NODISCARD std::string* Release(const std::string* default_value,
+                                          ::google::protobuf::Arena* arena);
+  PROTOBUF_NODISCARD std::string* ReleaseNonDefault(
       const std::string* default_value, ::google::protobuf::Arena* arena);
 
   // Takes a std::string that is heap-allocated, and takes ownership. The
diff --git a/src/google/protobuf/compiler/cpp/cpp_message.cc b/src/google/protobuf/compiler/cpp/cpp_message.cc
index 21faff3..95bbfde 100644
--- a/src/google/protobuf/compiler/cpp/cpp_message.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_message.cc
@@ -974,7 +974,7 @@
 template <typename _proto_TypeTraits,
           ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
           bool _is_packed>
-inline PROTOBUF_MUST_USE_RESULT
+PROTOBUF_NODISCARD inline
     typename _proto_TypeTraits::Singular::MutableType
     ReleaseExtension(
         const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
@@ -1649,11 +1649,7 @@
       "\n"
       "// implements Message ----------------------------------------------\n"
       "\n"
-      "inline $classname$* New() const final {\n"
-      "  return new $classname$();\n"
-      "}\n"
-      "\n"
-      "$classname$* New(::$proto_ns$::Arena* arena) const final {\n"
+      "$classname$* New(::$proto_ns$::Arena* arena = nullptr) const final {\n"
       "  return CreateMaybeMessage<$classname$>(arena);\n"
       "}\n");
 
@@ -1736,6 +1732,7 @@
 
   format(
       // Friend AnyMetadata so that it can call this FullMessageName() method.
+      "\nprivate:\n"
       "friend class ::$proto_ns$::internal::AnyMetadata;\n"
       "static $1$ FullMessageName() {\n"
       "  return \"$full_name$\";\n"
@@ -3115,7 +3112,9 @@
         "metadata_);\n");
 
     if (descriptor_->extension_range_count() > 0) {
-      format("_extensions_.MergeFrom(from._extensions_);\n");
+      format(
+          "_extensions_.MergeFrom(internal_default_instance(), "
+          "from._extensions_);\n");
     }
 
     GenerateConstructorBody(printer, processed, true);
@@ -3710,7 +3709,9 @@
   // Merging of extensions and unknown fields is done last, to maximize
   // the opportunity for tail calls.
   if (descriptor_->extension_range_count() > 0) {
-    format("_extensions_.MergeFrom(from._extensions_);\n");
+    format(
+        "_extensions_.MergeFrom(internal_default_instance(), "
+        "from._extensions_);\n");
   }
 
   format(
diff --git a/src/google/protobuf/compiler/cpp/cpp_message_field.cc b/src/google/protobuf/compiler/cpp/cpp_message_field.cc
index ee677ea..d6e05ea 100644
--- a/src/google/protobuf/compiler/cpp/cpp_message_field.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_message_field.cc
@@ -109,7 +109,7 @@
     format(
         "$deprecated_attr$const $type$& ${1$$name$$}$() const { "
         "__builtin_trap(); }\n"
-        "PROTOBUF_MUST_USE_RESULT $deprecated_attr$$type$* "
+        "PROTOBUF_NODISCARD $deprecated_attr$$type$* "
         "${1$$release_name$$}$() { "
         "__builtin_trap(); }\n"
         "$deprecated_attr$$type$* ${1$mutable_$name$$}$() { "
@@ -126,7 +126,7 @@
   }
   format(
       "$deprecated_attr$const $type$& ${1$$name$$}$() const;\n"
-      "PROTOBUF_MUST_USE_RESULT $deprecated_attr$$type$* "
+      "PROTOBUF_NODISCARD $deprecated_attr$$type$* "
       "${1$$release_name$$}$();\n"
       "$deprecated_attr$$type$* ${1$mutable_$name$$}$();\n"
       "$deprecated_attr$void ${1$set_allocated_$name$$}$"
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 cf26417..4a4f5e5 100644
--- a/src/google/protobuf/compiler/cpp/cpp_parse_function_generator.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_parse_function_generator.cc
@@ -766,15 +766,22 @@
                 "$msg$GetArenaForAllocation());\n"
                 "  $msg$set_has_$name$();\n"
                 "}\n"
-                "ptr = ctx->ParseMessage($msg$$1$_.$name$_, ptr);\n",
+                "auto* lazy_field = $msg$$1$_.$name$_;\n",
                 field->containing_oneof()->name());
           } else if (HasHasbit(field)) {
             format(
                 "_Internal::set_has_$name$(&$has_bits$);\n"
-                "ptr = ctx->ParseMessage(&$msg$$name$_, ptr);\n");
+                "auto* lazy_field = &$msg$$name$_;\n");
           } else {
-            format("ptr = ctx->ParseMessage(&$msg$$name$_, ptr);\n");
+            format("auto* lazy_field = &$msg$$name$_;\n");
           }
+          format(
+              "::$proto_ns$::internal::LazyFieldParseHelper<\n"
+              "  ::$proto_ns$::internal::LazyField> parse_helper(\n"
+              "    $1$::default_instance(),\n"
+              "    $msg$GetArenaForAllocation(), lazy_field);\n"
+              "ptr = ctx->ParseMessage(&parse_helper, ptr);\n",
+              FieldMessageTypeName(field, options_));
         } else if (IsImplicitWeakField(field, options_, scc_analyzer_)) {
           if (!field->is_repeated()) {
             format(
diff --git a/src/google/protobuf/compiler/cpp/cpp_string_field.cc b/src/google/protobuf/compiler/cpp/cpp_string_field.cc
index 93aff5d..607e815 100644
--- a/src/google/protobuf/compiler/cpp/cpp_string_field.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_string_field.cc
@@ -170,7 +170,7 @@
       descriptor_);
   format(
       "$deprecated_attr$std::string* ${1$mutable_$name$$}$();\n"
-      "PROTOBUF_MUST_USE_RESULT $deprecated_attr$std::string* "
+      "PROTOBUF_NODISCARD $deprecated_attr$std::string* "
       "${1$$release_name$$}$();\n"
       "$deprecated_attr$void ${1$set_allocated_$name$$}$(std::string* "
       "$name$);\n",
@@ -290,7 +290,7 @@
         "  $clear_hasbit$\n");
     if (!inlined_) {
       format(
-          "  return $name$_.ReleaseNonDefault($init_value$, "
+          "  auto* p = $name$_.ReleaseNonDefault($init_value$, "
           "GetArenaForAllocation());\n");
       if (descriptor_->default_value_string().empty()) {
         format(
@@ -300,6 +300,7 @@
             "  }\n"
             "#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING\n");
       }
+      format("  return p;\n");
     } else {
       format(
           "  return $name$_.Release(nullptr, GetArenaForAllocation(), "
diff --git a/src/google/protobuf/compiler/java/java_primitive_field.cc b/src/google/protobuf/compiler/java/java_primitive_field.cc
index 6e51c16..35f3bd7 100644
--- a/src/google/protobuf/compiler/java/java_primitive_field.cc
+++ b/src/google/protobuf/compiler/java/java_primitive_field.cc
@@ -618,8 +618,8 @@
 void ImmutablePrimitiveOneofFieldGenerator::GenerateParsingCode(
     io::Printer* printer) const {
   printer->Print(variables_,
-                 "$set_oneof_case_message$;\n"
-                 "$oneof_name$_ = input.read$capitalized_type$();\n");
+                 "$oneof_name$_ = input.read$capitalized_type$();\n"
+                 "$set_oneof_case_message$;\n");
 }
 
 void ImmutablePrimitiveOneofFieldGenerator::GenerateSerializationCode(
diff --git a/src/google/protobuf/compiler/objectivec/objectivec_file.cc b/src/google/protobuf/compiler/objectivec/objectivec_file.cc
index be2be2c..d9f43a5 100644
--- a/src/google/protobuf/compiler/objectivec/objectivec_file.cc
+++ b/src/google/protobuf/compiler/objectivec/objectivec_file.cc
@@ -52,7 +52,7 @@
 namespace {
 
 // This is also found in GPBBootstrap.h, and needs to be kept in sync.
-const int32 GOOGLE_PROTOBUF_OBJC_VERSION = 30004;
+const int32_t GOOGLE_PROTOBUF_OBJC_VERSION = 30004;
 
 const char* kHeaderExtension = ".pbobjc.h";
 
diff --git a/src/google/protobuf/compiler/objectivec/objectivec_generator.cc b/src/google/protobuf/compiler/objectivec/objectivec_generator.cc
index d5a2b6b..a03b860 100644
--- a/src/google/protobuf/compiler/objectivec/objectivec_generator.cc
+++ b/src/google/protobuf/compiler/objectivec/objectivec_generator.cc
@@ -44,6 +44,28 @@
 namespace compiler {
 namespace objectivec {
 
+namespace {
+
+// Convert a string with "yes"/"no" (case insensitive) to a boolean, returning
+// true/false for if the input string was a valid value. If the input string is
+// invalid, `result` is unchanged.
+bool StringToBool(const std::string& value, bool* result) {
+  std::string upper_value(value);
+  UpperString(&upper_value);
+  if (upper_value == "NO") {
+    *result = false;
+    return true;
+  }
+  if (upper_value == "YES") {
+    *result = true;
+    return true;
+  }
+
+  return false;
+}
+
+}  // namespace
+
 ObjectiveCGenerator::ObjectiveCGenerator() {}
 
 ObjectiveCGenerator::~ObjectiveCGenerator() {}
@@ -101,6 +123,31 @@
         generation_options.expected_prefixes_suppressions.push_back(
             std::string(split_piece));
       }
+    } else if (options[i].first == "prefixes_must_be_registered") {
+      // If objc prefix file option value must be registered to be used. This
+      // option has no meaning if an "expected_prefixes_path" isn't set. The
+      // available options are:
+      //   "no": They don't have to be registered.
+      //   "yes": They must be registered and an error will be raised if a files
+      //     tried to use a prefix that isn't registered.
+      // Default is "no".
+      if (!StringToBool(options[i].second,
+                        &generation_options.prefixes_must_be_registered)) {
+        *error = "error: Unknown value for prefixes_must_be_registered: " + options[i].second;
+        return false;
+      }
+    } else if (options[i].first == "require_prefixes") {
+      // If every file must have an objc prefix file option to be used. The
+      // available options are:
+      //   "no": Files can be generated without the prefix option.
+      //   "yes": Files must have the objc prefix option, and an error will be
+      //     raised if a files doesn't have one.
+      // Default is "no".
+      if (!StringToBool(options[i].second,
+                        &generation_options.require_prefixes)) {
+        *error = "error: Unknown value for require_prefixes: " + options[i].second;
+        return false;
+      }
     } else if (options[i].first == "generate_for_named_framework") {
       // The name of the framework that protos are being generated for. This
       // will cause the #import statements to be framework based using this
@@ -146,12 +193,9 @@
       // is just what to do if that isn't set. The available options are:
       //   "no": Not prefixed (the existing mode).
       //   "yes": Make a prefix out of the proto package.
-      std::string upper_value(options[i].second);
-      UpperString(&upper_value);
-      if (upper_value == "NO") {
-        SetUseProtoPackageAsDefaultPrefix(false);
-      } else if (upper_value == "YES") {
-        SetUseProtoPackageAsDefaultPrefix(true);
+      bool value = false;
+      if (StringToBool(options[i].second, &value)) {
+        SetUseProtoPackageAsDefaultPrefix(value);
       } else {
         *error = "error: Unknown use_package_as_prefix: " + options[i].second;
         return false;
diff --git a/src/google/protobuf/compiler/objectivec/objectivec_helpers.cc b/src/google/protobuf/compiler/objectivec/objectivec_helpers.cc
index 78491d2..5f4b7f6 100644
--- a/src/google/protobuf/compiler/objectivec/objectivec_helpers.cc
+++ b/src/google/protobuf/compiler/objectivec/objectivec_helpers.cc
@@ -178,6 +178,8 @@
     expected_prefixes_suppressions =
         Split(suppressions, ";", true);
   }
+  prefixes_must_be_registered = false;
+  require_prefixes = false;
 }
 
 namespace {
@@ -992,7 +994,7 @@
 
         // Must convert to a standard byte order for packing length into
         // a cstring.
-        uint32 length = ghtonl(default_string.length());
+        uint32_t length = ghtonl(default_string.length());
         std::string bytes((const char*)&length, sizeof(length));
         bytes.append(default_string);
         return "(NSData*)\"" + EscapeTrigraphs(CEscape(bytes)) + "\"";
@@ -1227,6 +1229,7 @@
 bool ValidateObjCClassPrefix(
     const FileDescriptor* file, const std::string& expected_prefixes_path,
     const std::map<std::string, std::string>& expected_package_prefixes,
+    bool prefixes_must_be_registered, bool require_prefixes,
     std::string* out_error) {
   // Reminder: An explicit prefix option of "" is valid in case the default
   // prefixing is set to use the proto package and a file needs to be generated
@@ -1265,6 +1268,12 @@
 
   // If there was no prefix option, we're done at this point.
   if (!has_prefix) {
+    if (require_prefixes) {
+      *out_error =
+        "error: '" + file->name() + "' does not have a required 'option" +
+        " objc_class_prefix'.";
+      return false;
+    }
     return true;
   }
 
@@ -1344,9 +1353,18 @@
     std::cerr.flush();
   }
 
-  // Check: Warning - If the given package/prefix pair wasn't expected, issue a
-  // warning suggesting it gets added to the file.
+  // Check: Error/Warning - If the given package/prefix pair wasn't expected,
+  // issue a error/warning to added to the file.
   if (have_expected_prefix_file) {
+    if (prefixes_must_be_registered) {
+      *out_error =
+        "error: '" + file->name() + "' has 'option objc_class_prefix = \"" +
+        prefix + "\";', but it is not registered; add it to the expected " +
+        "prefixes file (" + expected_prefixes_path + ") for the package '" +
+        package + "'.";
+      return false;
+    }
+
     std::cerr
          << "protoc:0: warning: Found unexpected 'option objc_class_prefix = \""
          << prefix << "\";' in '" << file->name() << "';"
@@ -1391,6 +1409,8 @@
         ValidateObjCClassPrefix(files[i],
                                 generation_options.expected_prefixes_path,
                                 expected_package_prefixes,
+                                generation_options.prefixes_must_be_registered,
+                                generation_options.require_prefixes,
                                 out_error);
     if (!is_valid) {
       return false;
@@ -1403,7 +1423,7 @@
 
 TextFormatDecodeData::~TextFormatDecodeData() { }
 
-void TextFormatDecodeData::AddString(int32 key,
+void TextFormatDecodeData::AddString(int32_t key,
                                      const std::string& input_for_decode,
                                      const std::string& desired_output) {
   for (std::vector<DataEntry>::const_iterator i = entries_.begin();
@@ -1459,12 +1479,12 @@
   }
 
  private:
-  static constexpr uint8 kAddUnderscore = 0x80;
+  static constexpr uint8_t kAddUnderscore = 0x80;
 
-  static constexpr uint8 kOpAsIs = 0x00;
-  static constexpr uint8 kOpFirstUpper = 0x40;
-  static constexpr uint8 kOpFirstLower = 0x20;
-  static constexpr uint8 kOpAllUpper = 0x60;
+  static constexpr uint8_t kOpAsIs = 0x00;
+  static constexpr uint8_t kOpFirstUpper = 0x40;
+  static constexpr uint8_t kOpFirstLower = 0x20;
+  static constexpr uint8_t kOpAllUpper = 0x60;
 
   static constexpr int kMaxSegmentLen = 0x1f;
 
@@ -1474,7 +1494,7 @@
   }
 
   void Push() {
-    uint8 op = (op_ | segment_len_);
+    uint8_t op = (op_ | segment_len_);
     if (need_underscore_) op |= kAddUnderscore;
     if (op != 0) {
       decode_data_ += (char)op;
@@ -1506,7 +1526,7 @@
 
   bool need_underscore_;
   bool is_all_upper_;
-  uint8 op_;
+  uint8_t op_;
   int segment_len_;
 
   std::string decode_data_;
@@ -1618,71 +1638,71 @@
   Parser(LineConsumer* line_consumer)
       : line_consumer_(line_consumer), line_(0) {}
 
-  // Parses a check of input, returning success/failure.
-  bool ParseChunk(StringPiece chunk);
+  // Feeds in some input, parse what it can, returning success/failure. Calling
+  // again after an error is undefined.
+  bool ParseChunk(StringPiece chunk, std::string* out_error);
 
   // Should be called to finish parsing (after all input has been provided via
-  // ParseChunk()).  Returns success/failure.
-  bool Finish();
+  // successful calls to ParseChunk(), calling after a ParseChunk() failure is
+  // undefined). Returns success/failure.
+  bool Finish(std::string* out_error);
 
   int last_line() const { return line_; }
-  std::string error_str() const { return error_str_; }
 
  private:
-  bool ParseLoop();
-
   LineConsumer* line_consumer_;
   int line_;
-  std::string error_str_;
-  StringPiece p_;
   std::string leftover_;
 };
 
-bool Parser::ParseChunk(StringPiece chunk) {
+bool Parser::ParseChunk(StringPiece chunk, std::string* out_error) {
+  StringPiece full_chunk;
   if (!leftover_.empty()) {
     leftover_ += std::string(chunk);
-    p_ = StringPiece(leftover_);
+    full_chunk = StringPiece(leftover_);
   } else {
-    p_ = chunk;
+    full_chunk = chunk;
   }
-  bool result = ParseLoop();
-  if (p_.empty()) {
-    leftover_.clear();
-  } else {
-    leftover_ = std::string(p_);
-  }
-  return result;
-}
 
-bool Parser::Finish() {
-  if (leftover_.empty()) {
-    return true;
-  }
-  // Force a newline onto the end to finish parsing.
-  leftover_ += "\n";
-  p_ = StringPiece(leftover_);
-  if (!ParseLoop()) {
-    return false;
-  }
-  return p_.empty();  // Everything used?
-}
-
-bool Parser::ParseLoop() {
   StringPiece line;
-  while (ReadLine(&p_, &line)) {
+  while (ReadLine(&full_chunk, &line)) {
     ++line_;
     RemoveComment(&line);
     TrimWhitespace(&line);
-    if (line.empty()) {
-      continue;  // Blank line.
-    }
-    if (!line_consumer_->ConsumeLine(line, &error_str_)) {
+    if (!line.empty() && !line_consumer_->ConsumeLine(line, out_error)) {
+      if (out_error->empty()) {
+        *out_error = "ConsumeLine failed without setting an error.";
+      }
+      leftover_.clear();
       return false;
     }
   }
+
+  if (full_chunk.empty()) {
+    leftover_.clear();
+  } else {
+    leftover_ = std::string(full_chunk);
+  }
   return true;
 }
 
+bool Parser::Finish(std::string* out_error) {
+  // If there is still something to go, flush it with a newline.
+  if (!leftover_.empty() && !ParseChunk("\n", out_error)) {
+    return false;
+  }
+  // This really should never fail if ParseChunk succeeded, but check to be sure.
+  if (!leftover_.empty()) {
+    *out_error = "ParseSimple Internal error: finished with pending data.";
+    return false;
+  }
+  return true;
+}
+
+std::string FullErrorString(const std::string& name, int line_num, const std::string& msg) {
+  return std::string("error: ") + name + " Line " + StrCat(line_num) + ", " + msg;
+}
+
 }  // namespace
 
 LineConsumer::LineConsumer() {}
@@ -1703,22 +1723,33 @@
   io::FileInputStream file_stream(fd);
   file_stream.SetCloseOnDelete(true);
 
+  return ParseSimpleStream(file_stream, path, line_consumer, out_error);
+}
+
+bool ParseSimpleStream(io::ZeroCopyInputStream& input_stream,
+                       const std::string& stream_name,
+                       LineConsumer* line_consumer,
+                       std::string* out_error) {
+  std::string local_error;
   Parser parser(line_consumer);
   const void* buf;
   int buf_len;
-  while (file_stream.Next(&buf, &buf_len)) {
+  while (input_stream.Next(&buf, &buf_len)) {
     if (buf_len == 0) {
       continue;
     }
 
-    if (!parser.ParseChunk(StringPiece(static_cast<const char*>(buf), buf_len))) {
-      *out_error =
-          std::string("error: ") + path +
-          " Line " + StrCat(parser.last_line()) + ", " + parser.error_str();
+    if (!parser.ParseChunk(StringPiece(static_cast<const char*>(buf), buf_len),
+                           &local_error)) {
+      *out_error = FullErrorString(stream_name, parser.last_line(), local_error);
       return false;
     }
   }
-  return parser.Finish();
+  if (!parser.Finish(&local_error)) {
+    *out_error = FullErrorString(stream_name, parser.last_line(), local_error);
+    return false;
+  }
+  return true;
 }
 
 ImportWriter::ImportWriter(
diff --git a/src/google/protobuf/compiler/objectivec/objectivec_helpers.h b/src/google/protobuf/compiler/objectivec/objectivec_helpers.h
index 02615e0..c5f948c 100644
--- a/src/google/protobuf/compiler/objectivec/objectivec_helpers.h
+++ b/src/google/protobuf/compiler/objectivec/objectivec_helpers.h
@@ -38,6 +38,7 @@
 
 #include <google/protobuf/descriptor.h>
 #include <google/protobuf/descriptor.pb.h>
+#include <google/protobuf/io/zero_copy_stream.h>
 
 #include <google/protobuf/port_def.inc>
 
@@ -67,6 +68,8 @@
   std::string generate_for_named_framework;
   std::string named_framework_to_proto_path_mappings_path;
   std::string runtime_import_prefix;
+  bool prefixes_must_be_registered;
+  bool require_prefixes;
 };
 
 // Escape C++ trigraphs by escaping question marks to "\?".
@@ -285,6 +288,11 @@
                                    LineConsumer* line_consumer,
                                    std::string* out_error);
 
+bool PROTOC_EXPORT ParseSimpleStream(io::ZeroCopyInputStream& input_stream,
+                                     const std::string& stream_name,
+                                     LineConsumer* line_consumer,
+                                     std::string* out_error);
+
 // Helper class for parsing framework import mappings and generating
 // import statements.
 class PROTOC_EXPORT ImportWriter {
diff --git a/src/google/protobuf/compiler/objectivec/objectivec_helpers_unittest.cc b/src/google/protobuf/compiler/objectivec/objectivec_helpers_unittest.cc
index 0aef94f..3c5eda2 100644
--- a/src/google/protobuf/compiler/objectivec/objectivec_helpers_unittest.cc
+++ b/src/google/protobuf/compiler/objectivec/objectivec_helpers_unittest.cc
@@ -29,6 +29,7 @@
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 #include <google/protobuf/compiler/objectivec/objectivec_helpers.h>
+#include <google/protobuf/io/zero_copy_stream_impl_lite.h>
 #include <google/protobuf/testing/googletest.h>
 #include <gtest/gtest.h>
 
@@ -242,6 +243,133 @@
 }
 #endif  // PROTOBUF_HAS_DEATH_TEST
 
+class TestLineCollector : public LineConsumer {
+ public:
+  TestLineCollector(std::vector<std::string>* inout_lines,
+                    const std::string* reject_line = nullptr,
+                    bool skip_msg = false)
+    : lines_(inout_lines), reject_(reject_line), skip_msg_(skip_msg) {}
+
+  bool ConsumeLine(const StringPiece& line, std::string* out_error) override {
+    if (reject_ && *reject_ == line) {
+      if (!skip_msg_) {
+        *out_error = std::string("Rejected '") + *reject_ + "'";
+      }
+      return false;
+    }
+    if (lines_) {
+      lines_->emplace_back(line);
+    }
+    return true;
+  }
+
+ private:
+  std::vector<std::string>* lines_;
+  const std::string* reject_;
+  bool skip_msg_;
+};
+
+const int kBlockSizes[] = {-1, 1, 2, 5, 64};
+const int kBlockSizeCount = GOOGLE_ARRAYSIZE(kBlockSizes);
+
+TEST(ObjCHelper, ParseSimple_BasicsSuccess) {
+  const std::vector<std::pair<std::string, std::vector<std::string>>> tests = {
+    {"", {}},
+    {"a", {"a"}},
+    {"a c", {"a c"}},
+    {" a c ", {"a c"}},
+    {"\ta c ", {"a c"}},
+    {"abc\n", {"abc"}},
+    {"abc\nd f", {"abc", "d f"}},
+    {"\n abc \n def \n\n", {"abc", "def"}},
+  };
+
+  for (const auto& test : tests) {
+    for (int i = 0; i < kBlockSizeCount; i++) {
+      io::ArrayInputStream input(test.first.data(), test.first.size(), kBlockSizes[i]);
+      std::string err_str;
+      std::vector<std::string> lines;
+      TestLineCollector collector(&lines);
+      EXPECT_TRUE(ParseSimpleStream(input, "dummy", &collector, &err_str));
+      EXPECT_EQ(lines, test.second);
+      EXPECT_TRUE(err_str.empty());
+    }
+  }
+}
+
+TEST(ObjCHelper, ParseSimple_DropsComments) {
+  const std::vector<std::pair<std::string, std::vector<std::string>>> tests = {
+    {"# nothing", {}},
+    {"#", {}},
+    {"##", {}},
+    {"\n# nothing\n", {}},
+    {"a # same line", {"a"}},
+    {"a # same line\n", {"a"}},
+    {"a\n# line\nc", {"a", "c"}},
+    {"# n o t # h i n g #", {}},
+    {"## n o # t h i n g #", {}},
+    {"a# n o t # h i n g #", {"a"}},
+    {"a\n## n o # t h i n g #", {"a"}},
+  };
+
+  for (const auto& test : tests) {
+    for (int i = 0; i < kBlockSizeCount; i++) {
+      io::ArrayInputStream input(test.first.data(), test.first.size(), kBlockSizes[i]);
+      std::string err_str;
+      std::vector<std::string> lines;
+      TestLineCollector collector(&lines);
+      EXPECT_TRUE(ParseSimpleStream(input, "dummy", &collector, &err_str));
+      EXPECT_EQ(lines, test.second);
+      EXPECT_TRUE(err_str.empty());
+    }
+  }
+}
+
+TEST(ObjCHelper, ParseSimple_RejectLines) {
+  const std::vector<std::tuple<std::string, std::string, int>> tests = {
+    std::make_tuple("a\nb\nc", "a", 1),
+    std::make_tuple("a\nb\nc", "b", 2),
+    std::make_tuple("a\nb\nc", "c", 3),
+    std::make_tuple("a\nb\nc\n", "c", 3),
+  };
+
+  for (const auto& test : tests) {
+    for (int i = 0; i < kBlockSizeCount; i++) {
+      io::ArrayInputStream input(std::get<0>(test).data(), std::get<0>(test).size(),
+                                 kBlockSizes[i]);
+      std::string err_str;
+      TestLineCollector collector(nullptr, &std::get<1>(test));
+      EXPECT_FALSE(ParseSimpleStream(input, "dummy", &collector, &err_str));
+      std::string expected_err =
+        StrCat("error: dummy Line ", std::get<2>(test), ", Rejected '", std::get<1>(test), "'");
+      EXPECT_EQ(err_str, expected_err);
+    }
+  }
+}
+
+TEST(ObjCHelper, ParseSimple_RejectLinesNoMessage) {
+  const std::vector<std::tuple<std::string, std::string, int>> tests = {
+    std::make_tuple("a\nb\nc", "a", 1),
+    std::make_tuple("a\nb\nc", "b", 2),
+    std::make_tuple("a\nb\nc", "c", 3),
+    std::make_tuple("a\nb\nc\n", "c", 3),
+  };
+
+  for (const auto& test : tests) {
+    for (int i = 0; i < kBlockSizeCount; i++) {
+      io::ArrayInputStream input(std::get<0>(test).data(), std::get<0>(test).size(),
+                                 kBlockSizes[i]);
+      std::string err_str;
+      TestLineCollector collector(nullptr, &std::get<1>(test), true /* skip msg */);
+      EXPECT_FALSE(ParseSimpleStream(input, "dummy", &collector, &err_str));
+      std::string expected_err =
+        StrCat("error: dummy Line ", std::get<2>(test),
+               ", ConsumeLine failed without setting an error.");
+      EXPECT_EQ(err_str, expected_err);
+    }
+  }
+}
+
 // TODO(thomasvl): Should probably add some unittests for all the special cases
 // of name mangling (class name, field name, enum names).  Rather than doing
 // this with an ObjC test in the objectivec directory, we should be able to
diff --git a/src/google/protobuf/compiler/plugin.pb.h b/src/google/protobuf/compiler/plugin.pb.h
index 5ed6e55..20d8169 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 < 3017000
+#if PROTOBUF_VERSION < 3018000
 #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 3017003 < PROTOBUF_MIN_PROTOC_VERSION
+#if 3018000 < 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.
@@ -192,11 +192,7 @@
 
   // implements Message ----------------------------------------------
 
-  inline Version* New() const final {
-    return new Version();
-  }
-
-  Version* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final {
+  Version* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final {
     return CreateMaybeMessage<Version>(arena);
   }
   using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom;
@@ -220,6 +216,8 @@
   void SharedDtor();
   void SetCachedSize(int size) const final;
   void InternalSwap(Version* other);
+
+  private:
   friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
   static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
     return "google.protobuf.compiler.Version";
@@ -257,7 +255,7 @@
   template <typename ArgT0 = const std::string&, typename... ArgT>
   void set_suffix(ArgT0&& arg0, ArgT... args);
   std::string* mutable_suffix();
-  PROTOBUF_MUST_USE_RESULT std::string* release_suffix();
+  PROTOBUF_NODISCARD std::string* release_suffix();
   void set_allocated_suffix(std::string* suffix);
   private:
   const std::string& _internal_suffix() const;
@@ -402,11 +400,7 @@
 
   // implements Message ----------------------------------------------
 
-  inline CodeGeneratorRequest* New() const final {
-    return new CodeGeneratorRequest();
-  }
-
-  CodeGeneratorRequest* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final {
+  CodeGeneratorRequest* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final {
     return CreateMaybeMessage<CodeGeneratorRequest>(arena);
   }
   using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom;
@@ -430,6 +424,8 @@
   void SharedDtor();
   void SetCachedSize(int size) const final;
   void InternalSwap(CodeGeneratorRequest* other);
+
+  private:
   friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
   static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
     return "google.protobuf.compiler.CodeGeneratorRequest";
@@ -509,7 +505,7 @@
   template <typename ArgT0 = const std::string&, typename... ArgT>
   void set_parameter(ArgT0&& arg0, ArgT... args);
   std::string* mutable_parameter();
-  PROTOBUF_MUST_USE_RESULT std::string* release_parameter();
+  PROTOBUF_NODISCARD std::string* release_parameter();
   void set_allocated_parameter(std::string* parameter);
   private:
   const std::string& _internal_parameter() const;
@@ -524,7 +520,7 @@
   public:
   void clear_compiler_version();
   const ::PROTOBUF_NAMESPACE_ID::compiler::Version& compiler_version() const;
-  PROTOBUF_MUST_USE_RESULT ::PROTOBUF_NAMESPACE_ID::compiler::Version* release_compiler_version();
+  PROTOBUF_NODISCARD ::PROTOBUF_NAMESPACE_ID::compiler::Version* release_compiler_version();
   ::PROTOBUF_NAMESPACE_ID::compiler::Version* mutable_compiler_version();
   void set_allocated_compiler_version(::PROTOBUF_NAMESPACE_ID::compiler::Version* compiler_version);
   private:
@@ -633,11 +629,7 @@
 
   // implements Message ----------------------------------------------
 
-  inline CodeGeneratorResponse_File* New() const final {
-    return new CodeGeneratorResponse_File();
-  }
-
-  CodeGeneratorResponse_File* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final {
+  CodeGeneratorResponse_File* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final {
     return CreateMaybeMessage<CodeGeneratorResponse_File>(arena);
   }
   using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom;
@@ -661,6 +653,8 @@
   void SharedDtor();
   void SetCachedSize(int size) const final;
   void InternalSwap(CodeGeneratorResponse_File* other);
+
+  private:
   friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
   static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
     return "google.protobuf.compiler.CodeGeneratorResponse.File";
@@ -698,7 +692,7 @@
   template <typename ArgT0 = const std::string&, typename... ArgT>
   void set_name(ArgT0&& arg0, ArgT... args);
   std::string* mutable_name();
-  PROTOBUF_MUST_USE_RESULT std::string* release_name();
+  PROTOBUF_NODISCARD std::string* release_name();
   void set_allocated_name(std::string* name);
   private:
   const std::string& _internal_name() const;
@@ -716,7 +710,7 @@
   template <typename ArgT0 = const std::string&, typename... ArgT>
   void set_insertion_point(ArgT0&& arg0, ArgT... args);
   std::string* mutable_insertion_point();
-  PROTOBUF_MUST_USE_RESULT std::string* release_insertion_point();
+  PROTOBUF_NODISCARD std::string* release_insertion_point();
   void set_allocated_insertion_point(std::string* insertion_point);
   private:
   const std::string& _internal_insertion_point() const;
@@ -734,7 +728,7 @@
   template <typename ArgT0 = const std::string&, typename... ArgT>
   void set_content(ArgT0&& arg0, ArgT... args);
   std::string* mutable_content();
-  PROTOBUF_MUST_USE_RESULT std::string* release_content();
+  PROTOBUF_NODISCARD std::string* release_content();
   void set_allocated_content(std::string* content);
   private:
   const std::string& _internal_content() const;
@@ -749,7 +743,7 @@
   public:
   void clear_generated_code_info();
   const ::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo& generated_code_info() const;
-  PROTOBUF_MUST_USE_RESULT ::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo* release_generated_code_info();
+  PROTOBUF_NODISCARD ::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo* release_generated_code_info();
   ::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo* mutable_generated_code_info();
   void set_allocated_generated_code_info(::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo* generated_code_info);
   private:
@@ -858,11 +852,7 @@
 
   // implements Message ----------------------------------------------
 
-  inline CodeGeneratorResponse* New() const final {
-    return new CodeGeneratorResponse();
-  }
-
-  CodeGeneratorResponse* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final {
+  CodeGeneratorResponse* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final {
     return CreateMaybeMessage<CodeGeneratorResponse>(arena);
   }
   using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom;
@@ -886,6 +876,8 @@
   void SharedDtor();
   void SetCachedSize(int size) const final;
   void InternalSwap(CodeGeneratorResponse* other);
+
+  private:
   friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
   static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
     return "google.protobuf.compiler.CodeGeneratorResponse";
@@ -972,7 +964,7 @@
   template <typename ArgT0 = const std::string&, typename... ArgT>
   void set_error(ArgT0&& arg0, ArgT... args);
   std::string* mutable_error();
-  PROTOBUF_MUST_USE_RESULT std::string* release_error();
+  PROTOBUF_NODISCARD std::string* release_error();
   void set_allocated_error(std::string* error);
   private:
   const std::string& _internal_error() const;
@@ -1147,12 +1139,13 @@
     return nullptr;
   }
   _has_bits_[0] &= ~0x00000001u;
-  return suffix_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation());
+  auto* p = suffix_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation());
 #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
   if (suffix_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) {
     suffix_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
   }
 #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+  return p;
 }
 inline void Version::set_allocated_suffix(std::string* suffix) {
   if (suffix != nullptr) {
@@ -1294,12 +1287,13 @@
     return nullptr;
   }
   _has_bits_[0] &= ~0x00000001u;
-  return parameter_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation());
+  auto* p = parameter_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation());
 #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
   if (parameter_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) {
     parameter_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
   }
 #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+  return p;
 }
 inline void CodeGeneratorRequest::set_allocated_parameter(std::string* parameter) {
   if (parameter != nullptr) {
@@ -1493,12 +1487,13 @@
     return nullptr;
   }
   _has_bits_[0] &= ~0x00000001u;
-  return name_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation());
+  auto* p = name_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation());
 #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
   if (name_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) {
     name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
   }
 #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+  return p;
 }
 inline void CodeGeneratorResponse_File::set_allocated_name(std::string* name) {
   if (name != nullptr) {
@@ -1561,12 +1556,13 @@
     return nullptr;
   }
   _has_bits_[0] &= ~0x00000002u;
-  return insertion_point_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation());
+  auto* p = insertion_point_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation());
 #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
   if (insertion_point_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) {
     insertion_point_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
   }
 #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+  return p;
 }
 inline void CodeGeneratorResponse_File::set_allocated_insertion_point(std::string* insertion_point) {
   if (insertion_point != nullptr) {
@@ -1629,12 +1625,13 @@
     return nullptr;
   }
   _has_bits_[0] &= ~0x00000004u;
-  return content_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation());
+  auto* p = content_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation());
 #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
   if (content_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) {
     content_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
   }
 #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+  return p;
 }
 inline void CodeGeneratorResponse_File::set_allocated_content(std::string* content) {
   if (content != nullptr) {
@@ -1789,12 +1786,13 @@
     return nullptr;
   }
   _has_bits_[0] &= ~0x00000001u;
-  return error_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation());
+  auto* p = error_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation());
 #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
   if (error_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) {
     error_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
   }
 #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+  return p;
 }
 inline void CodeGeneratorResponse::set_allocated_error(std::string* error) {
   if (error != nullptr) {
diff --git a/src/google/protobuf/compiler/python/python_generator.cc b/src/google/protobuf/compiler/python/python_generator.cc
index 8db99ab..9ad7a33 100644
--- a/src/google/protobuf/compiler/python/python_generator.cc
+++ b/src/google/protobuf/compiler/python/python_generator.cc
@@ -803,8 +803,7 @@
     m["name"] = desc->name();
     m["full_name"] = desc->full_name();
     m["index"] = StrCat(desc->index());
-    options_string =
-        OptionsValue(desc->options().SerializeAsString());
+    options_string = OptionsValue(desc->options().SerializeAsString());
     if (options_string == "None") {
       m["serialized_options"] = "";
     } else {
diff --git a/src/google/protobuf/compiler/ruby/ruby_generated_code.proto b/src/google/protobuf/compiler/ruby/ruby_generated_code.proto
index 42d82a6..70ec9f1 100644
--- a/src/google/protobuf/compiler/ruby/ruby_generated_code.proto
+++ b/src/google/protobuf/compiler/ruby/ruby_generated_code.proto
@@ -2,6 +2,8 @@
 
 package A.B.C;
 
+import "ruby_generated_code_proto2_import.proto";
+
 message TestMessage {
   int32 optional_int32 = 1;
   int64 optional_int64 = 2;
@@ -14,6 +16,7 @@
   bytes optional_bytes = 9;
   TestEnum optional_enum = 10;
   TestMessage optional_msg = 11;
+  TestImportedMessage optional_proto2_submessage = 12;
 
   repeated int32 repeated_int32 = 21;
   repeated int64 repeated_int64 = 22;
diff --git a/src/google/protobuf/compiler/ruby/ruby_generated_code_pb.rb b/src/google/protobuf/compiler/ruby/ruby_generated_code_pb.rb
index 7e66d1e..4cf4866 100644
--- a/src/google/protobuf/compiler/ruby/ruby_generated_code_pb.rb
+++ b/src/google/protobuf/compiler/ruby/ruby_generated_code_pb.rb
@@ -1,6 +1,7 @@
 # Generated by the protocol buffer compiler.  DO NOT EDIT!
 # source: ruby_generated_code.proto
 
+require 'ruby_generated_code_proto2_import_pb'
 require 'google/protobuf'
 
 Google::Protobuf::DescriptorPool.generated_pool.build do
@@ -17,6 +18,7 @@
       optional :optional_bytes, :bytes, 9
       optional :optional_enum, :enum, 10, "A.B.C.TestEnum"
       optional :optional_msg, :message, 11, "A.B.C.TestMessage"
+      optional :optional_proto2_submessage, :message, 12, "A.B.C.TestImportedMessage"
       repeated :repeated_int32, :int32, 21
       repeated :repeated_int64, :int64, 22
       repeated :repeated_uint32, :uint32, 23
diff --git a/src/google/protobuf/compiler/ruby/ruby_generated_code_proto2.proto b/src/google/protobuf/compiler/ruby/ruby_generated_code_proto2.proto
index 8d3cc13..ea7f783 100644
--- a/src/google/protobuf/compiler/ruby/ruby_generated_code_proto2.proto
+++ b/src/google/protobuf/compiler/ruby/ruby_generated_code_proto2.proto
@@ -2,6 +2,8 @@
 
 package A.B.C;
 
+import "ruby_generated_code_proto2_import.proto";
+
 message TestMessage {
   optional int32 optional_int32 = 1 [default = 1];
   optional int64 optional_int64 = 2 [default = 2];
@@ -14,6 +16,7 @@
   optional bytes optional_bytes = 9 [default = "\0\1\2\100fubar"];
   optional TestEnum optional_enum = 10 [default = A];
   optional TestMessage optional_msg = 11;
+  optional TestImportedMessage optional_proto2_submessage = 12;
 
   repeated int32 repeated_int32 = 21;
   repeated int64 repeated_int64 = 22;
diff --git a/src/google/protobuf/compiler/ruby/ruby_generated_code_proto2_import.proto b/src/google/protobuf/compiler/ruby/ruby_generated_code_proto2_import.proto
new file mode 100644
index 0000000..9ec0738
--- /dev/null
+++ b/src/google/protobuf/compiler/ruby/ruby_generated_code_proto2_import.proto
@@ -0,0 +1,5 @@
+syntax = "proto2";
+
+package A.B.C;
+
+message TestImportedMessage {}
diff --git a/src/google/protobuf/compiler/ruby/ruby_generated_code_proto2_pb.rb b/src/google/protobuf/compiler/ruby/ruby_generated_code_proto2_pb.rb
index c89738f..e331e9b 100644
--- a/src/google/protobuf/compiler/ruby/ruby_generated_code_proto2_pb.rb
+++ b/src/google/protobuf/compiler/ruby/ruby_generated_code_proto2_pb.rb
@@ -1,6 +1,7 @@
 # Generated by the protocol buffer compiler.  DO NOT EDIT!
 # source: ruby_generated_code_proto2.proto
 
+require 'ruby_generated_code_proto2_import_pb'
 require 'google/protobuf'
 
 Google::Protobuf::DescriptorPool.generated_pool.build do
@@ -17,6 +18,7 @@
       optional :optional_bytes, :bytes, 9, default: "\x00\x01\x02\x40\x66\x75\x62\x61\x72".force_encoding("ASCII-8BIT")
       optional :optional_enum, :enum, 10, "A.B.C.TestEnum", default: 1
       optional :optional_msg, :message, 11, "A.B.C.TestMessage"
+      optional :optional_proto2_submessage, :message, 12, "A.B.C.TestImportedMessage"
       repeated :repeated_int32, :int32, 21
       repeated :repeated_int64, :int64, 22
       repeated :repeated_uint32, :uint32, 23
diff --git a/src/google/protobuf/compiler/ruby/ruby_generator.cc b/src/google/protobuf/compiler/ruby/ruby_generator.cc
index 2cee902..c1a5c67 100644
--- a/src/google/protobuf/compiler/ruby/ruby_generator.cc
+++ b/src/google/protobuf/compiler/ruby/ruby_generator.cc
@@ -465,68 +465,6 @@
   }
 }
 
-bool UsesTypeFromFile(const Descriptor* message, const FileDescriptor* file,
-                      std::string* error) {
-  for (int i = 0; i < message->field_count(); i++) {
-    const FieldDescriptor* field = message->field(i);
-    if ((field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE &&
-         field->message_type()->file() == file) ||
-        (field->type() == FieldDescriptor::TYPE_ENUM &&
-         field->enum_type()->file() == file)) {
-      *error = "proto3 message field " + field->full_name() + " in file " +
-               file->name() + " has a dependency on a type from proto2 file " +
-               file->name() +
-               ".  Ruby doesn't support proto2 yet, so we must fail.";
-      return true;
-    }
-  }
-
-  for (int i = 0; i < message->nested_type_count(); i++) {
-    if (UsesTypeFromFile(message->nested_type(i), file, error)) {
-      return true;
-    }
-  }
-
-  return false;
-}
-
-// Ruby doesn't currently support proto2.  This causes a failure even for proto3
-// files that import proto2.  But in some cases, the proto2 file is only being
-// imported to extend another proto2 message.  The prime example is declaring
-// custom options by extending FileOptions/FieldOptions/etc.
-//
-// If the proto3 messages don't have any proto2 submessages, it is safe to omit
-// the dependency completely.  Users won't be able to use any proto2 extensions,
-// but they already couldn't because proto2 messages aren't supported.
-//
-// If/when we add proto2 support, we should remove this.
-bool MaybeEmitDependency(const FileDescriptor* import,
-                         const FileDescriptor* from,
-                         io::Printer* printer,
-                         std::string* error) {
-  if (from->syntax() == FileDescriptor::SYNTAX_PROTO3 &&
-      import->syntax() == FileDescriptor::SYNTAX_PROTO2) {
-    for (int i = 0; i < from->message_type_count(); i++) {
-      if (UsesTypeFromFile(from->message_type(i), import, error)) {
-        // Error text was already set by UsesTypeFromFile().
-        return false;
-      }
-    }
-
-    // Ok to omit this proto2 dependency -- so we won't print anything.
-    GOOGLE_LOG(WARNING) << "Omitting proto2 dependency '" << import->name()
-                        << "' from proto3 output file '"
-                        << GetOutputFilename(from->name())
-                        << "' because we don't support proto2 and no proto2 "
-                           "types from that file are being used.";
-    return true;
-  } else {
-    printer->Print(
-      "require '$name$'\n", "name", GetRequireName(import->name()));
-    return true;
-  }
-}
-
 bool GenerateDslDescriptor(const FileDescriptor* file, io::Printer* printer,
                            std::string* error) {
   printer->Print(
@@ -572,9 +510,7 @@
     "filename", file->name());
 
   for (int i = 0; i < file->dependency_count(); i++) {
-    if (!MaybeEmitDependency(file->dependency(i), file, printer, error)) {
-      return false;
-    }
+    printer->Print("require '$name$'\n", "name", GetRequireName(file->dependency(i)->name()));
   }
 
   // TODO: Remove this when ruby supports extensions for proto2 syntax.
diff --git a/src/google/protobuf/compiler/ruby/ruby_generator_unittest.cc b/src/google/protobuf/compiler/ruby/ruby_generator_unittest.cc
index 27439a7..040b6c9 100644
--- a/src/google/protobuf/compiler/ruby/ruby_generator_unittest.cc
+++ b/src/google/protobuf/compiler/ruby/ruby_generator_unittest.cc
@@ -57,7 +57,7 @@
 // Some day, we may integrate build systems between protoc and the language
 // extensions to the point where we can do this test in a more automated way.
 
-void RubyTest(string proto_file) {
+void RubyTest(string proto_file, string import_proto_file = "") {
   std::string ruby_tests = FindRubyTestDir();
 
   google::protobuf::compiler::CommandLineInterface cli;
@@ -77,9 +77,23 @@
       test_input,
       true));
 
+  // Copy generated_code_import.proto to the temporary test directory.
+  std::string test_import;
+  if (!import_proto_file.empty()) {
+    GOOGLE_CHECK_OK(File::GetContents(
+        ruby_tests + import_proto_file + ".proto",
+        &test_import,
+        true));
+    GOOGLE_CHECK_OK(File::SetContents(
+        TestTempDir() + import_proto_file + ".proto",
+        test_import,
+        true));
+  }
+
   // Invoke the proto compiler (we will be inside TestTempDir() at this point).
   std::string ruby_out = "--ruby_out=" + TestTempDir();
   std::string proto_path = "--proto_path=" + TestTempDir();
+
   std::string proto_target = TestTempDir() + proto_file + ".proto";
   const char* argv[] = {
     "protoc",
@@ -105,11 +119,11 @@
 }
 
 TEST(RubyGeneratorTest, Proto3GeneratorTest) {
-  RubyTest("/ruby_generated_code");
+  RubyTest("/ruby_generated_code", "/ruby_generated_code_proto2_import");
 }
 
 TEST(RubyGeneratorTest, Proto2GeneratorTest) {
-    RubyTest("/ruby_generated_code_proto2");
+    RubyTest("/ruby_generated_code_proto2", "/ruby_generated_code_proto2_import");
 }
 
 TEST(RubyGeneratorTest, Proto3ImplicitPackageTest) {
diff --git a/src/google/protobuf/descriptor.cc b/src/google/protobuf/descriptor.cc
index 00e3e15..924c23b 100644
--- a/src/google/protobuf/descriptor.cc
+++ b/src/google/protobuf/descriptor.cc
@@ -156,6 +156,7 @@
   struct QueryKey : internal::SymbolBase {
     StringPiece name;
     const void* parent;
+    int field_number;
   };
   DEFINE_MEMBERS(QueryKey, QUERY_KEY, query_key);
 #undef DEFINE_MEMBERS
@@ -220,7 +221,7 @@
     return "";
   }
 
-  std::pair<const void*, StringPiece> parent_key() const {
+  std::pair<const void*, StringPiece> parent_name_key() const {
     const auto or_file = [&](const void* p) { return p ? p : GetFile(); };
     switch (type()) {
       case MESSAGE:
@@ -255,6 +256,22 @@
     return {};
   }
 
+  std::pair<const void*, int> parent_number_key() const {
+    switch (type()) {
+      case FIELD:
+        return {field_descriptor()->containing_type(),
+                field_descriptor()->number()};
+      case ENUM_VALUE:
+        return {enum_value_descriptor()->type(),
+                enum_value_descriptor()->number()};
+      case QUERY_KEY:
+        return {query_key()->parent, query_key()->field_number};
+      default:
+        GOOGLE_CHECK(false);
+    }
+    return {};
+  }
+
  private:
   const internal::SymbolBase* ptr_;
 };
@@ -499,7 +516,6 @@
 typedef std::pair<const void*, StringPiece> PointerStringPair;
 
 typedef std::pair<const Descriptor*, int> DescriptorIntPair;
-typedef std::pair<const EnumDescriptor*, int> EnumIntPair;
 
 #define HASH_MAP std::unordered_map
 #define HASH_SET std::unordered_set
@@ -561,12 +577,12 @@
 
 struct SymbolByParentHash {
   size_t operator()(Symbol s) const {
-    return PointerStringPairHash{}(s.parent_key());
+    return PointerStringPairHash{}(s.parent_name_key());
   }
 };
 struct SymbolByParentEq {
   bool operator()(Symbol a, Symbol b) const {
-    return a.parent_key() == b.parent_key();
+    return a.parent_name_key() == b.parent_name_key();
   }
 };
 using SymbolsByParentSet =
@@ -580,15 +596,21 @@
                  PointerStringPairHash>
     FieldsByNameMap;
 
-typedef HASH_MAP<DescriptorIntPair, const FieldDescriptor*,
-                 PointerIntegerPairHash<DescriptorIntPair>,
-                 std::equal_to<DescriptorIntPair>>
-    FieldsByNumberMap;
+struct FieldsByNumberHash {
+  size_t operator()(Symbol s) const {
+    return PointerIntegerPairHash<std::pair<const void*, int>>{}(
+        s.parent_number_key());
+  }
+};
+struct FieldsByNumberEq {
+  bool operator()(Symbol a, Symbol b) const {
+    return a.parent_number_key() == b.parent_number_key();
+  }
+};
+using FieldsByNumberSet =
+    HASH_SET<Symbol, FieldsByNumberHash, FieldsByNumberEq>;
+using EnumValuesByNumberSet = FieldsByNumberSet;
 
-typedef HASH_MAP<EnumIntPair, const EnumValueDescriptor*,
-                 PointerIntegerPairHash<EnumIntPair>,
-                 std::equal_to<EnumIntPair>>
-    EnumValuesByNumberMap;
 // This is a map rather than a hash-map, since we use it to iterate
 // through all the extensions that extend a given Descriptor, and an
 // ordered data structure that implements lower_bound is convenient
@@ -1268,8 +1290,8 @@
   // as it will be used as a key in the symbols_by_parent_ map without copying.
   bool AddAliasUnderParent(const void* parent, const std::string& name,
                            Symbol symbol);
-  bool AddFieldByNumber(const FieldDescriptor* field);
-  bool AddEnumValueByNumber(const EnumValueDescriptor* value);
+  bool AddFieldByNumber(FieldDescriptor* field);
+  bool AddEnumValueByNumber(EnumValueDescriptor* value);
 
   // Adds the field to the lowercase_name and camelcase_name maps.  Never
   // fails because we allow duplicates; the first field by the name wins.
@@ -1307,9 +1329,9 @@
   mutable FieldsByNameMap fields_by_camelcase_name_;
   std::unique_ptr<FieldsByNameMap> fields_by_camelcase_name_tmp_;
   mutable internal::once_flag fields_by_camelcase_name_once_;
-  FieldsByNumberMap fields_by_number_;  // Not including extensions.
-  EnumValuesByNumberMap enum_values_by_number_;
-  mutable EnumValuesByNumberMap unknown_enum_values_by_number_
+  FieldsByNumberSet fields_by_number_;  // Not including extensions.
+  EnumValuesByNumberSet enum_values_by_number_;
+  mutable EnumValuesByNumberSet unknown_enum_values_by_number_
       PROTOBUF_GUARDED_BY(unknown_enum_values_mu_);
 
   // Populated on first request to save space, hence constness games.
@@ -1459,7 +1481,19 @@
 
 inline const FieldDescriptor* FileDescriptorTables::FindFieldByNumber(
     const Descriptor* parent, int number) const {
-  return FindPtrOrNull(fields_by_number_, std::make_pair(parent, number));
+  // If `number` is within the sequential range, just index into the parent
+  // without doing a table lookup.
+  if (parent != nullptr &&  //
+      1 <= number && number <= parent->sequential_field_limit_) {
+    return parent->field(number - 1);
+  }
+
+  Symbol::QueryKey query;
+  query.parent = parent;
+  query.field_number = number;
+
+  auto it = fields_by_number_.find(Symbol(&query));
+  return it == fields_by_number_.end() ? nullptr : it->field_descriptor();
 }
 
 const void* FileDescriptorTables::FindParentForFieldsByMap(
@@ -1481,12 +1515,12 @@
 }
 
 void FileDescriptorTables::FieldsByLowercaseNamesLazyInitInternal() const {
-  for (FieldsByNumberMap::const_iterator it = fields_by_number_.begin();
-       it != fields_by_number_.end(); it++) {
-    PointerStringPair lowercase_key(FindParentForFieldsByMap(it->second),
-                                    it->second->lowercase_name().c_str());
-    InsertIfNotPresent(&fields_by_lowercase_name_, lowercase_key,
-                            it->second);
+  for (Symbol symbol : symbols_by_parent_) {
+    const FieldDescriptor* field = symbol.field_descriptor();
+    if (!field) continue;
+    PointerStringPair lowercase_key(FindParentForFieldsByMap(field),
+                                    field->lowercase_name().c_str());
+    InsertIfNotPresent(&fields_by_lowercase_name_, lowercase_key, field);
   }
 }
 
@@ -1505,12 +1539,12 @@
 }
 
 void FileDescriptorTables::FieldsByCamelcaseNamesLazyInitInternal() const {
-  for (FieldsByNumberMap::const_iterator it = fields_by_number_.begin();
-       it != fields_by_number_.end(); it++) {
-    PointerStringPair camelcase_key(FindParentForFieldsByMap(it->second),
-                                    it->second->camelcase_name().c_str());
-    InsertIfNotPresent(&fields_by_camelcase_name_, camelcase_key,
-                            it->second);
+  for (Symbol symbol : symbols_by_parent_) {
+    const FieldDescriptor* field = symbol.field_descriptor();
+    if (!field) continue;
+    PointerStringPair camelcase_key(FindParentForFieldsByMap(field),
+                                    field->camelcase_name().c_str());
+    InsertIfNotPresent(&fields_by_camelcase_name_, camelcase_key, field);
   }
 }
 
@@ -1525,8 +1559,21 @@
 
 inline const EnumValueDescriptor* FileDescriptorTables::FindEnumValueByNumber(
     const EnumDescriptor* parent, int number) const {
-  return FindPtrOrNull(enum_values_by_number_,
-                            std::make_pair(parent, number));
+  // If `number` is within the sequential range, just index into the parent
+  // without doing a table lookup.
+  const int base = parent->value(0)->number();
+  if (base <= number &&
+      number <= static_cast<int64_t>(base) + parent->sequential_value_limit_) {
+    return parent->value(number - base);
+  }
+
+  Symbol::QueryKey query;
+  query.parent = parent;
+  query.field_number = number;
+
+  auto it = enum_values_by_number_.find(Symbol(&query));
+  return it == enum_values_by_number_.end() ? nullptr
+                                            : it->enum_value_descriptor();
 }
 
 inline const EnumValueDescriptor*
@@ -1534,29 +1581,33 @@
     const EnumDescriptor* parent, int number) const {
   // First try, with map of compiled-in values.
   {
-    const EnumValueDescriptor* desc = FindPtrOrNull(
-        enum_values_by_number_, std::make_pair(parent, number));
-    if (desc != nullptr) {
-      return desc;
+    const auto* value = FindEnumValueByNumber(parent, number);
+    if (value != nullptr) {
+      return value;
     }
   }
+
+  Symbol::QueryKey query;
+  query.parent = parent;
+  query.field_number = number;
+
   // Second try, with reader lock held on unknown enum values: common case.
   {
     ReaderMutexLock l(&unknown_enum_values_mu_);
-    const EnumValueDescriptor* desc = FindPtrOrNull(
-        unknown_enum_values_by_number_, std::make_pair(parent, number));
-    if (desc != nullptr) {
-      return desc;
+    auto it = unknown_enum_values_by_number_.find(Symbol(&query));
+    if (it != unknown_enum_values_by_number_.end() &&
+        it->enum_value_descriptor() != nullptr) {
+      return it->enum_value_descriptor();
     }
   }
   // If not found, try again with writer lock held, and create new descriptor if
   // necessary.
   {
     WriterMutexLock l(&unknown_enum_values_mu_);
-    const EnumValueDescriptor* desc = FindPtrOrNull(
-        unknown_enum_values_by_number_, std::make_pair(parent, number));
-    if (desc != nullptr) {
-      return desc;
+    auto it = unknown_enum_values_by_number_.find(Symbol(&query));
+    if (it != unknown_enum_values_by_number_.end() &&
+        it->enum_value_descriptor() != nullptr) {
+      return it->enum_value_descriptor();
     }
 
     // Create an EnumValueDescriptor dynamically. We don't insert it into the
@@ -1565,17 +1616,21 @@
     // later.
     std::string enum_value_name = StringPrintf("UNKNOWN_ENUM_VALUE_%s_%d",
                                                parent->name().c_str(), number);
-    DescriptorPool::Tables* tables = const_cast<DescriptorPool::Tables*>(
-        DescriptorPool::generated_pool()->tables_.get());
-    EnumValueDescriptor* result = tables->Allocate<EnumValueDescriptor>();
-    result->all_names_ = tables->AllocateStringArray(
-        enum_value_name,
-        StrCat(parent->full_name(), ".", enum_value_name));
+    auto* pool = DescriptorPool::generated_pool();
+    auto* tables = const_cast<DescriptorPool::Tables*>(pool->tables_.get());
+    EnumValueDescriptor* result;
+    {
+      // Must lock the pool because we will do allocations in the shared arena.
+      MutexLockMaybe l2(pool->mutex_);
+      result = tables->Allocate<EnumValueDescriptor>();
+      result->all_names_ = tables->AllocateStringArray(
+          enum_value_name,
+          StrCat(parent->full_name(), ".", enum_value_name));
+    }
     result->number_ = number;
     result->type_ = parent;
     result->options_ = &EnumValueOptions::default_instance();
-    InsertIfNotPresent(&unknown_enum_values_by_number_,
-                            std::make_pair(parent, number), result);
+    unknown_enum_values_by_number_.insert(Symbol::EnumValue(result, 0));
     return result;
   }
 }
@@ -1611,8 +1666,8 @@
 bool FileDescriptorTables::AddAliasUnderParent(const void* parent,
                                                const std::string& name,
                                                Symbol symbol) {
-  GOOGLE_DCHECK_EQ(name, symbol.parent_key().second);
-  GOOGLE_DCHECK_EQ(parent, symbol.parent_key().first);
+  GOOGLE_DCHECK_EQ(name, symbol.parent_name_key().second);
+  GOOGLE_DCHECK_EQ(parent, symbol.parent_name_key().first);
   return symbols_by_parent_.insert(symbol).second;
 }
 
@@ -1659,15 +1714,30 @@
   }
 }
 
-bool FileDescriptorTables::AddFieldByNumber(const FieldDescriptor* field) {
-  DescriptorIntPair key(field->containing_type(), field->number());
-  return InsertIfNotPresent(&fields_by_number_, key, field);
+bool FileDescriptorTables::AddFieldByNumber(FieldDescriptor* field) {
+  // Skip fields that are at the start of the sequence.
+  if (field->containing_type() != nullptr && field->number() >= 1 &&
+      field->number() <= field->containing_type()->sequential_field_limit_) {
+    if (field->is_extension()) {
+      // Conflicts with the field that already exists in the sequential range.
+      return false;
+    }
+    // Only return true if the field at that index matches. Otherwise it
+    // conflicts with the existing field in the sequential range.
+    return field->containing_type()->field(field->number() - 1) == field;
+  }
+
+  return fields_by_number_.insert(Symbol(field)).second;
 }
 
-bool FileDescriptorTables::AddEnumValueByNumber(
-    const EnumValueDescriptor* value) {
-  EnumIntPair key(value->type(), value->number());
-  return InsertIfNotPresent(&enum_values_by_number_, key, value);
+bool FileDescriptorTables::AddEnumValueByNumber(EnumValueDescriptor* value) {
+  // Skip values that are at the start of the sequence.
+  const int base = value->type()->value(0)->number();
+  if (base <= value->number() &&
+      value->number() <=
+          static_cast<int64_t>(base) + value->type()->sequential_value_limit_)
+    return true;
+  return enum_values_by_number_.insert(Symbol::EnumValue(value, 0)).second;
 }
 
 bool DescriptorPool::Tables::AddExtension(const FieldDescriptor* field) {
@@ -2489,25 +2559,18 @@
   switch (cpp_type()) {
     case CPPTYPE_INT32:
       return StrCat(default_value_int32_t());
-      break;
     case CPPTYPE_INT64:
       return StrCat(default_value_int64_t());
-      break;
     case CPPTYPE_UINT32:
       return StrCat(default_value_uint32_t());
-      break;
     case CPPTYPE_UINT64:
       return StrCat(default_value_uint64_t());
-      break;
     case CPPTYPE_FLOAT:
       return SimpleFtoa(default_value_float());
-      break;
     case CPPTYPE_DOUBLE:
       return SimpleDtoa(default_value_double());
-      break;
     case CPPTYPE_BOOL:
       return default_value_bool() ? "true" : "false";
-      break;
     case CPPTYPE_STRING:
       if (quote_string_type) {
         return "\"" + CEscape(default_value_string()) + "\"";
@@ -2518,10 +2581,8 @@
           return default_value_string();
         }
       }
-      break;
     case CPPTYPE_ENUM:
       return default_value_enum()->name();
-      break;
     case CPPTYPE_MESSAGE:
       GOOGLE_LOG(DFATAL) << "Messages can't have default values!";
       break;
@@ -4457,6 +4518,8 @@
     // Enums must have at least one value.
     placeholder_enum->value_count_ = 1;
     placeholder_enum->values_ = tables_->AllocateArray<EnumValueDescriptor>(1);
+    // Disable fast-path lookup for this enum.
+    placeholder_enum->sequential_value_limit_ = -1;
 
     EnumValueDescriptor* placeholder_value = &placeholder_enum->values_[0];
     memset(static_cast<void*>(placeholder_value), 0,
@@ -5131,6 +5194,19 @@
     result->well_known_type_ = it->second;
   }
 
+  // Calculate the continuous sequence of fields.
+  // These can be fast-path'd during lookup and don't need to be added to the
+  // tables.
+  // We use uint16_t to save space for sequential_field_limit_, so stop before
+  // overflowing it. Worst case, we are not taking full advantage on huge
+  // messages, but it is unlikely.
+  result->sequential_field_limit_ = 0;
+  for (int i = 0; i < std::numeric_limits<uint16_t>::max() &&
+                  i < proto.field_size() && proto.field(i).number() == i + 1;
+       ++i) {
+    result->sequential_field_limit_ = i + 1;
+  }
+
   // Build oneofs first so that fields and extension ranges can refer to them.
   BUILD_ARRAY(proto, result, oneof_decl, BuildOneof, result);
   BUILD_ARRAY(proto, result, field, BuildField, result);
@@ -5693,6 +5769,21 @@
              "Enums must contain at least one value.");
   }
 
+  // Calculate the continuous sequence of the labels.
+  // These can be fast-path'd during lookup and don't need to be added to the
+  // tables.
+  // We use uint16_t to save space for sequential_value_limit_, so stop before
+  // overflowing it. Worst case, we are not taking full advantage on huge
+  // enums, but it is unlikely.
+  for (int i = 0;
+       i < std::numeric_limits<uint16_t>::max() && i < proto.value_size() &&
+       // We do the math in int64_t to avoid overflows.
+       proto.value(i).number() ==
+           static_cast<int64_t>(i) + proto.value(0).number();
+       ++i) {
+    result->sequential_value_limit_ = i;
+  }
+
   BUILD_ARRAY(proto, result, value, BuildEnumValue, result);
   BUILD_ARRAY(proto, result, reserved_range, BuildReservedRange, result);
 
diff --git a/src/google/protobuf/descriptor.h b/src/google/protobuf/descriptor.h
index a87f1cb..e74e355 100644
--- a/src/google/protobuf/descriptor.h
+++ b/src/google/protobuf/descriptor.h
@@ -542,8 +542,18 @@
   bool is_placeholder_ : 1;
   // True if this is a placeholder and the type name wasn't fully-qualified.
   bool is_unqualified_placeholder_ : 1;
-  // Well known type.  Stored as char to conserve space.
-  char well_known_type_;
+  // Well known type.  Stored like this to conserve space.
+  uint8_t well_known_type_ : 5;
+
+  // This points to the last field _number_ that is part of the sequence
+  // starting at 1, where
+  //     `desc->field(i)->number() == i + 1`
+  // A value of `0` means no field matches. That is, there are no fields or the
+  // first field is not field `1`.
+  // Uses 16-bit to avoid extra padding. Unlikely to have more than 2^16
+  // sequentially numbered fields in a message.
+  uint16_t sequential_field_limit_;
+
   int field_count_;
 
   // all_names_ = [name, full_name]
@@ -581,6 +591,7 @@
   friend class DescriptorPool;
   friend class EnumDescriptor;
   friend class FieldDescriptor;
+  friend class FileDescriptorTables;
   friend class OneofDescriptor;
   friend class MethodDescriptor;
   friend class FileDescriptor;
@@ -1145,6 +1156,9 @@
   friend class io::Printer;
   friend class compiler::cpp::Formatter;
 
+  // Allow access to FindValueByNumberCreatingIfUnknown.
+  friend class descriptor_unittest::DescriptorTest;
+
   // Looks up a value by number.  If the value does not exist, dynamically
   // creates a new EnumValueDescriptor for that value, assuming that it was
   // unknown. If a new descriptor is created, this is done in a thread-safe way,
@@ -1165,9 +1179,18 @@
   void GetLocationPath(std::vector<int>* output) const;
 
   // True if this is a placeholder for an unknown type.
-  bool is_placeholder_;
+  bool is_placeholder_ : 1;
   // True if this is a placeholder and the type name wasn't fully-qualified.
-  bool is_unqualified_placeholder_;
+  bool is_unqualified_placeholder_ : 1;
+
+  // This points to the last value _index_ that is part of the sequence starting
+  // with the first label, where
+  //   `enum->value(i)->number() == enum->value(0)->number() + i`
+  // We measure relative to the first label to adapt to enum labels starting at
+  // 0 or 1.
+  // Uses 16-bit to avoid extra padding. Unlikely to have more than 2^15
+  // sequentially numbered labels in an enum.
+  int16_t sequential_value_limit_;
 
   int value_count_;
 
@@ -1192,6 +1215,7 @@
   friend class DescriptorBuilder;
   friend class Descriptor;
   friend class FieldDescriptor;
+  friend class FileDescriptorTables;
   friend class EnumValueDescriptor;
   friend class FileDescriptor;
   friend class DescriptorPool;
diff --git a/src/google/protobuf/descriptor.pb.cc b/src/google/protobuf/descriptor.pb.cc
index 1e6a472..6f7a5af 100644
--- a/src/google/protobuf/descriptor.pb.cc
+++ b/src/google/protobuf/descriptor.pb.cc
@@ -3226,7 +3226,7 @@
   : ::PROTOBUF_NAMESPACE_ID::Message(),
       uninterpreted_option_(from.uninterpreted_option_) {
   _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
-  _extensions_.MergeFrom(from._extensions_);
+  _extensions_.MergeFrom(internal_default_instance(), from._extensions_);
   // @@protoc_insertion_point(copy_constructor:google.protobuf.ExtensionRangeOptions)
 }
 
@@ -3378,7 +3378,7 @@
   (void) cached_has_bits;
 
   uninterpreted_option_.MergeFrom(from.uninterpreted_option_);
-  _extensions_.MergeFrom(from._extensions_);
+  _extensions_.MergeFrom(internal_default_instance(), from._extensions_);
   _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
 }
 
@@ -6135,7 +6135,7 @@
       _has_bits_(from._has_bits_),
       uninterpreted_option_(from.uninterpreted_option_) {
   _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
-  _extensions_.MergeFrom(from._extensions_);
+  _extensions_.MergeFrom(internal_default_instance(), from._extensions_);
   java_package_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
   #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
     java_package_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
@@ -7049,7 +7049,7 @@
     }
     _has_bits_[0] |= cached_has_bits;
   }
-  _extensions_.MergeFrom(from._extensions_);
+  _extensions_.MergeFrom(internal_default_instance(), from._extensions_);
   _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
 }
 
@@ -7178,7 +7178,7 @@
       _has_bits_(from._has_bits_),
       uninterpreted_option_(from.uninterpreted_option_) {
   _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
-  _extensions_.MergeFrom(from._extensions_);
+  _extensions_.MergeFrom(internal_default_instance(), from._extensions_);
   ::memcpy(&message_set_wire_format_, &from.message_set_wire_format_,
     static_cast<size_t>(reinterpret_cast<char*>(&map_entry_) -
     reinterpret_cast<char*>(&message_set_wire_format_)) + sizeof(map_entry_));
@@ -7443,7 +7443,7 @@
     }
     _has_bits_[0] |= cached_has_bits;
   }
-  _extensions_.MergeFrom(from._extensions_);
+  _extensions_.MergeFrom(internal_default_instance(), from._extensions_);
   _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
 }
 
@@ -7524,7 +7524,7 @@
       _has_bits_(from._has_bits_),
       uninterpreted_option_(from.uninterpreted_option_) {
   _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
-  _extensions_.MergeFrom(from._extensions_);
+  _extensions_.MergeFrom(internal_default_instance(), from._extensions_);
   ::memcpy(&ctype_, &from.ctype_,
     static_cast<size_t>(reinterpret_cast<char*>(&jstype_) -
     reinterpret_cast<char*>(&ctype_)) + sizeof(jstype_));
@@ -7850,7 +7850,7 @@
     }
     _has_bits_[0] |= cached_has_bits;
   }
-  _extensions_.MergeFrom(from._extensions_);
+  _extensions_.MergeFrom(internal_default_instance(), from._extensions_);
   _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
 }
 
@@ -7911,7 +7911,7 @@
   : ::PROTOBUF_NAMESPACE_ID::Message(),
       uninterpreted_option_(from.uninterpreted_option_) {
   _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
-  _extensions_.MergeFrom(from._extensions_);
+  _extensions_.MergeFrom(internal_default_instance(), from._extensions_);
   // @@protoc_insertion_point(copy_constructor:google.protobuf.OneofOptions)
 }
 
@@ -8063,7 +8063,7 @@
   (void) cached_has_bits;
 
   uninterpreted_option_.MergeFrom(from.uninterpreted_option_);
-  _extensions_.MergeFrom(from._extensions_);
+  _extensions_.MergeFrom(internal_default_instance(), from._extensions_);
   _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
 }
 
@@ -8125,7 +8125,7 @@
       _has_bits_(from._has_bits_),
       uninterpreted_option_(from.uninterpreted_option_) {
   _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
-  _extensions_.MergeFrom(from._extensions_);
+  _extensions_.MergeFrom(internal_default_instance(), from._extensions_);
   ::memcpy(&allow_alias_, &from.allow_alias_,
     static_cast<size_t>(reinterpret_cast<char*>(&deprecated_) -
     reinterpret_cast<char*>(&allow_alias_)) + sizeof(deprecated_));
@@ -8344,7 +8344,7 @@
     }
     _has_bits_[0] |= cached_has_bits;
   }
-  _extensions_.MergeFrom(from._extensions_);
+  _extensions_.MergeFrom(internal_default_instance(), from._extensions_);
   _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
 }
 
@@ -8410,7 +8410,7 @@
       _has_bits_(from._has_bits_),
       uninterpreted_option_(from.uninterpreted_option_) {
   _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
-  _extensions_.MergeFrom(from._extensions_);
+  _extensions_.MergeFrom(internal_default_instance(), from._extensions_);
   deprecated_ = from.deprecated_;
   // @@protoc_insertion_point(copy_constructor:google.protobuf.EnumValueOptions)
 }
@@ -8593,7 +8593,7 @@
   if (from._internal_has_deprecated()) {
     _internal_set_deprecated(from._internal_deprecated());
   }
-  _extensions_.MergeFrom(from._extensions_);
+  _extensions_.MergeFrom(internal_default_instance(), from._extensions_);
   _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
 }
 
@@ -8654,7 +8654,7 @@
       _has_bits_(from._has_bits_),
       uninterpreted_option_(from.uninterpreted_option_) {
   _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
-  _extensions_.MergeFrom(from._extensions_);
+  _extensions_.MergeFrom(internal_default_instance(), from._extensions_);
   deprecated_ = from.deprecated_;
   // @@protoc_insertion_point(copy_constructor:google.protobuf.ServiceOptions)
 }
@@ -8837,7 +8837,7 @@
   if (from._internal_has_deprecated()) {
     _internal_set_deprecated(from._internal_deprecated());
   }
-  _extensions_.MergeFrom(from._extensions_);
+  _extensions_.MergeFrom(internal_default_instance(), from._extensions_);
   _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
 }
 
@@ -8901,7 +8901,7 @@
       _has_bits_(from._has_bits_),
       uninterpreted_option_(from.uninterpreted_option_) {
   _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
-  _extensions_.MergeFrom(from._extensions_);
+  _extensions_.MergeFrom(internal_default_instance(), from._extensions_);
   ::memcpy(&deprecated_, &from.deprecated_,
     static_cast<size_t>(reinterpret_cast<char*>(&idempotency_level_) -
     reinterpret_cast<char*>(&deprecated_)) + sizeof(idempotency_level_));
@@ -9129,7 +9129,7 @@
     }
     _has_bits_[0] |= cached_has_bits;
   }
-  _extensions_.MergeFrom(from._extensions_);
+  _extensions_.MergeFrom(internal_default_instance(), from._extensions_);
   _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
 }
 
diff --git a/src/google/protobuf/descriptor.pb.h b/src/google/protobuf/descriptor.pb.h
index 16a6c3b..9695983 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 < 3017000
+#if PROTOBUF_VERSION < 3018000
 #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 3017003 < PROTOBUF_MIN_PROTOC_VERSION
+#if 3018000 < 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.
@@ -410,11 +410,7 @@
 
   // implements Message ----------------------------------------------
 
-  inline FileDescriptorSet* New() const final {
-    return new FileDescriptorSet();
-  }
-
-  FileDescriptorSet* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final {
+  FileDescriptorSet* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final {
     return CreateMaybeMessage<FileDescriptorSet>(arena);
   }
   using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom;
@@ -438,6 +434,8 @@
   void SharedDtor();
   void SetCachedSize(int size) const final;
   void InternalSwap(FileDescriptorSet* other);
+
+  private:
   friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
   static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
     return "google.protobuf.FileDescriptorSet";
@@ -574,11 +572,7 @@
 
   // implements Message ----------------------------------------------
 
-  inline FileDescriptorProto* New() const final {
-    return new FileDescriptorProto();
-  }
-
-  FileDescriptorProto* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final {
+  FileDescriptorProto* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final {
     return CreateMaybeMessage<FileDescriptorProto>(arena);
   }
   using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom;
@@ -602,6 +596,8 @@
   void SharedDtor();
   void SetCachedSize(int size) const final;
   void InternalSwap(FileDescriptorProto* other);
+
+  private:
   friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
   static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
     return "google.protobuf.FileDescriptorProto";
@@ -787,7 +783,7 @@
   template <typename ArgT0 = const std::string&, typename... ArgT>
   void set_name(ArgT0&& arg0, ArgT... args);
   std::string* mutable_name();
-  PROTOBUF_MUST_USE_RESULT std::string* release_name();
+  PROTOBUF_NODISCARD std::string* release_name();
   void set_allocated_name(std::string* name);
   private:
   const std::string& _internal_name() const;
@@ -805,7 +801,7 @@
   template <typename ArgT0 = const std::string&, typename... ArgT>
   void set_package(ArgT0&& arg0, ArgT... args);
   std::string* mutable_package();
-  PROTOBUF_MUST_USE_RESULT std::string* release_package();
+  PROTOBUF_NODISCARD std::string* release_package();
   void set_allocated_package(std::string* package);
   private:
   const std::string& _internal_package() const;
@@ -823,7 +819,7 @@
   template <typename ArgT0 = const std::string&, typename... ArgT>
   void set_syntax(ArgT0&& arg0, ArgT... args);
   std::string* mutable_syntax();
-  PROTOBUF_MUST_USE_RESULT std::string* release_syntax();
+  PROTOBUF_NODISCARD std::string* release_syntax();
   void set_allocated_syntax(std::string* syntax);
   private:
   const std::string& _internal_syntax() const;
@@ -838,7 +834,7 @@
   public:
   void clear_options();
   const ::PROTOBUF_NAMESPACE_ID::FileOptions& options() const;
-  PROTOBUF_MUST_USE_RESULT ::PROTOBUF_NAMESPACE_ID::FileOptions* release_options();
+  PROTOBUF_NODISCARD ::PROTOBUF_NAMESPACE_ID::FileOptions* release_options();
   ::PROTOBUF_NAMESPACE_ID::FileOptions* mutable_options();
   void set_allocated_options(::PROTOBUF_NAMESPACE_ID::FileOptions* options);
   private:
@@ -856,7 +852,7 @@
   public:
   void clear_source_code_info();
   const ::PROTOBUF_NAMESPACE_ID::SourceCodeInfo& source_code_info() const;
-  PROTOBUF_MUST_USE_RESULT ::PROTOBUF_NAMESPACE_ID::SourceCodeInfo* release_source_code_info();
+  PROTOBUF_NODISCARD ::PROTOBUF_NAMESPACE_ID::SourceCodeInfo* release_source_code_info();
   ::PROTOBUF_NAMESPACE_ID::SourceCodeInfo* mutable_source_code_info();
   void set_allocated_source_code_info(::PROTOBUF_NAMESPACE_ID::SourceCodeInfo* source_code_info);
   private:
@@ -973,11 +969,7 @@
 
   // implements Message ----------------------------------------------
 
-  inline DescriptorProto_ExtensionRange* New() const final {
-    return new DescriptorProto_ExtensionRange();
-  }
-
-  DescriptorProto_ExtensionRange* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final {
+  DescriptorProto_ExtensionRange* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final {
     return CreateMaybeMessage<DescriptorProto_ExtensionRange>(arena);
   }
   using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom;
@@ -1001,6 +993,8 @@
   void SharedDtor();
   void SetCachedSize(int size) const final;
   void InternalSwap(DescriptorProto_ExtensionRange* other);
+
+  private:
   friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
   static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
     return "google.protobuf.DescriptorProto.ExtensionRange";
@@ -1034,7 +1028,7 @@
   public:
   void clear_options();
   const ::PROTOBUF_NAMESPACE_ID::ExtensionRangeOptions& options() const;
-  PROTOBUF_MUST_USE_RESULT ::PROTOBUF_NAMESPACE_ID::ExtensionRangeOptions* release_options();
+  PROTOBUF_NODISCARD ::PROTOBUF_NAMESPACE_ID::ExtensionRangeOptions* release_options();
   ::PROTOBUF_NAMESPACE_ID::ExtensionRangeOptions* mutable_options();
   void set_allocated_options(::PROTOBUF_NAMESPACE_ID::ExtensionRangeOptions* options);
   private:
@@ -1168,11 +1162,7 @@
 
   // implements Message ----------------------------------------------
 
-  inline DescriptorProto_ReservedRange* New() const final {
-    return new DescriptorProto_ReservedRange();
-  }
-
-  DescriptorProto_ReservedRange* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final {
+  DescriptorProto_ReservedRange* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final {
     return CreateMaybeMessage<DescriptorProto_ReservedRange>(arena);
   }
   using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom;
@@ -1196,6 +1186,8 @@
   void SharedDtor();
   void SetCachedSize(int size) const final;
   void InternalSwap(DescriptorProto_ReservedRange* other);
+
+  private:
   friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
   static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
     return "google.protobuf.DescriptorProto.ReservedRange";
@@ -1343,11 +1335,7 @@
 
   // implements Message ----------------------------------------------
 
-  inline DescriptorProto* New() const final {
-    return new DescriptorProto();
-  }
-
-  DescriptorProto* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final {
+  DescriptorProto* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final {
     return CreateMaybeMessage<DescriptorProto>(arena);
   }
   using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom;
@@ -1371,6 +1359,8 @@
   void SharedDtor();
   void SetCachedSize(int size) const final;
   void InternalSwap(DescriptorProto* other);
+
+  private:
   friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
   static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
     return "google.protobuf.DescriptorProto";
@@ -1567,7 +1557,7 @@
   template <typename ArgT0 = const std::string&, typename... ArgT>
   void set_name(ArgT0&& arg0, ArgT... args);
   std::string* mutable_name();
-  PROTOBUF_MUST_USE_RESULT std::string* release_name();
+  PROTOBUF_NODISCARD std::string* release_name();
   void set_allocated_name(std::string* name);
   private:
   const std::string& _internal_name() const;
@@ -1582,7 +1572,7 @@
   public:
   void clear_options();
   const ::PROTOBUF_NAMESPACE_ID::MessageOptions& options() const;
-  PROTOBUF_MUST_USE_RESULT ::PROTOBUF_NAMESPACE_ID::MessageOptions* release_options();
+  PROTOBUF_NODISCARD ::PROTOBUF_NAMESPACE_ID::MessageOptions* release_options();
   ::PROTOBUF_NAMESPACE_ID::MessageOptions* mutable_options();
   void set_allocated_options(::PROTOBUF_NAMESPACE_ID::MessageOptions* options);
   private:
@@ -1697,11 +1687,7 @@
 
   // implements Message ----------------------------------------------
 
-  inline ExtensionRangeOptions* New() const final {
-    return new ExtensionRangeOptions();
-  }
-
-  ExtensionRangeOptions* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final {
+  ExtensionRangeOptions* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final {
     return CreateMaybeMessage<ExtensionRangeOptions>(arena);
   }
   using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom;
@@ -1725,6 +1711,8 @@
   void SharedDtor();
   void SetCachedSize(int size) const final;
   void InternalSwap(ExtensionRangeOptions* other);
+
+  private:
   friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
   static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
     return "google.protobuf.ExtensionRangeOptions";
@@ -1856,7 +1844,7 @@
   template <typename _proto_TypeTraits,
             ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
             bool _is_packed>
-  inline PROTOBUF_MUST_USE_RESULT
+  PROTOBUF_NODISCARD inline
       typename _proto_TypeTraits::Singular::MutableType
       ReleaseExtension(
           const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
@@ -2053,11 +2041,7 @@
 
   // implements Message ----------------------------------------------
 
-  inline FieldDescriptorProto* New() const final {
-    return new FieldDescriptorProto();
-  }
-
-  FieldDescriptorProto* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final {
+  FieldDescriptorProto* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final {
     return CreateMaybeMessage<FieldDescriptorProto>(arena);
   }
   using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom;
@@ -2081,6 +2065,8 @@
   void SharedDtor();
   void SetCachedSize(int size) const final;
   void InternalSwap(FieldDescriptorProto* other);
+
+  private:
   friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
   static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
     return "google.protobuf.FieldDescriptorProto";
@@ -2219,7 +2205,7 @@
   template <typename ArgT0 = const std::string&, typename... ArgT>
   void set_name(ArgT0&& arg0, ArgT... args);
   std::string* mutable_name();
-  PROTOBUF_MUST_USE_RESULT std::string* release_name();
+  PROTOBUF_NODISCARD std::string* release_name();
   void set_allocated_name(std::string* name);
   private:
   const std::string& _internal_name() const;
@@ -2237,7 +2223,7 @@
   template <typename ArgT0 = const std::string&, typename... ArgT>
   void set_extendee(ArgT0&& arg0, ArgT... args);
   std::string* mutable_extendee();
-  PROTOBUF_MUST_USE_RESULT std::string* release_extendee();
+  PROTOBUF_NODISCARD std::string* release_extendee();
   void set_allocated_extendee(std::string* extendee);
   private:
   const std::string& _internal_extendee() const;
@@ -2255,7 +2241,7 @@
   template <typename ArgT0 = const std::string&, typename... ArgT>
   void set_type_name(ArgT0&& arg0, ArgT... args);
   std::string* mutable_type_name();
-  PROTOBUF_MUST_USE_RESULT std::string* release_type_name();
+  PROTOBUF_NODISCARD std::string* release_type_name();
   void set_allocated_type_name(std::string* type_name);
   private:
   const std::string& _internal_type_name() const;
@@ -2273,7 +2259,7 @@
   template <typename ArgT0 = const std::string&, typename... ArgT>
   void set_default_value(ArgT0&& arg0, ArgT... args);
   std::string* mutable_default_value();
-  PROTOBUF_MUST_USE_RESULT std::string* release_default_value();
+  PROTOBUF_NODISCARD std::string* release_default_value();
   void set_allocated_default_value(std::string* default_value);
   private:
   const std::string& _internal_default_value() const;
@@ -2291,7 +2277,7 @@
   template <typename ArgT0 = const std::string&, typename... ArgT>
   void set_json_name(ArgT0&& arg0, ArgT... args);
   std::string* mutable_json_name();
-  PROTOBUF_MUST_USE_RESULT std::string* release_json_name();
+  PROTOBUF_NODISCARD std::string* release_json_name();
   void set_allocated_json_name(std::string* json_name);
   private:
   const std::string& _internal_json_name() const;
@@ -2306,7 +2292,7 @@
   public:
   void clear_options();
   const ::PROTOBUF_NAMESPACE_ID::FieldOptions& options() const;
-  PROTOBUF_MUST_USE_RESULT ::PROTOBUF_NAMESPACE_ID::FieldOptions* release_options();
+  PROTOBUF_NODISCARD ::PROTOBUF_NAMESPACE_ID::FieldOptions* release_options();
   ::PROTOBUF_NAMESPACE_ID::FieldOptions* mutable_options();
   void set_allocated_options(::PROTOBUF_NAMESPACE_ID::FieldOptions* options);
   private:
@@ -2487,11 +2473,7 @@
 
   // implements Message ----------------------------------------------
 
-  inline OneofDescriptorProto* New() const final {
-    return new OneofDescriptorProto();
-  }
-
-  OneofDescriptorProto* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final {
+  OneofDescriptorProto* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final {
     return CreateMaybeMessage<OneofDescriptorProto>(arena);
   }
   using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom;
@@ -2515,6 +2497,8 @@
   void SharedDtor();
   void SetCachedSize(int size) const final;
   void InternalSwap(OneofDescriptorProto* other);
+
+  private:
   friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
   static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
     return "google.protobuf.OneofDescriptorProto";
@@ -2550,7 +2534,7 @@
   template <typename ArgT0 = const std::string&, typename... ArgT>
   void set_name(ArgT0&& arg0, ArgT... args);
   std::string* mutable_name();
-  PROTOBUF_MUST_USE_RESULT std::string* release_name();
+  PROTOBUF_NODISCARD std::string* release_name();
   void set_allocated_name(std::string* name);
   private:
   const std::string& _internal_name() const;
@@ -2565,7 +2549,7 @@
   public:
   void clear_options();
   const ::PROTOBUF_NAMESPACE_ID::OneofOptions& options() const;
-  PROTOBUF_MUST_USE_RESULT ::PROTOBUF_NAMESPACE_ID::OneofOptions* release_options();
+  PROTOBUF_NODISCARD ::PROTOBUF_NAMESPACE_ID::OneofOptions* release_options();
   ::PROTOBUF_NAMESPACE_ID::OneofOptions* mutable_options();
   void set_allocated_options(::PROTOBUF_NAMESPACE_ID::OneofOptions* options);
   private:
@@ -2672,11 +2656,7 @@
 
   // implements Message ----------------------------------------------
 
-  inline EnumDescriptorProto_EnumReservedRange* New() const final {
-    return new EnumDescriptorProto_EnumReservedRange();
-  }
-
-  EnumDescriptorProto_EnumReservedRange* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final {
+  EnumDescriptorProto_EnumReservedRange* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final {
     return CreateMaybeMessage<EnumDescriptorProto_EnumReservedRange>(arena);
   }
   using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom;
@@ -2700,6 +2680,8 @@
   void SharedDtor();
   void SetCachedSize(int size) const final;
   void InternalSwap(EnumDescriptorProto_EnumReservedRange* other);
+
+  private:
   friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
   static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
     return "google.protobuf.EnumDescriptorProto.EnumReservedRange";
@@ -2847,11 +2829,7 @@
 
   // implements Message ----------------------------------------------
 
-  inline EnumDescriptorProto* New() const final {
-    return new EnumDescriptorProto();
-  }
-
-  EnumDescriptorProto* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final {
+  EnumDescriptorProto* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final {
     return CreateMaybeMessage<EnumDescriptorProto>(arena);
   }
   using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom;
@@ -2875,6 +2853,8 @@
   void SharedDtor();
   void SetCachedSize(int size) const final;
   void InternalSwap(EnumDescriptorProto* other);
+
+  private:
   friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
   static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
     return "google.protobuf.EnumDescriptorProto";
@@ -2975,7 +2955,7 @@
   template <typename ArgT0 = const std::string&, typename... ArgT>
   void set_name(ArgT0&& arg0, ArgT... args);
   std::string* mutable_name();
-  PROTOBUF_MUST_USE_RESULT std::string* release_name();
+  PROTOBUF_NODISCARD std::string* release_name();
   void set_allocated_name(std::string* name);
   private:
   const std::string& _internal_name() const;
@@ -2990,7 +2970,7 @@
   public:
   void clear_options();
   const ::PROTOBUF_NAMESPACE_ID::EnumOptions& options() const;
-  PROTOBUF_MUST_USE_RESULT ::PROTOBUF_NAMESPACE_ID::EnumOptions* release_options();
+  PROTOBUF_NODISCARD ::PROTOBUF_NAMESPACE_ID::EnumOptions* release_options();
   ::PROTOBUF_NAMESPACE_ID::EnumOptions* mutable_options();
   void set_allocated_options(::PROTOBUF_NAMESPACE_ID::EnumOptions* options);
   private:
@@ -3100,11 +3080,7 @@
 
   // implements Message ----------------------------------------------
 
-  inline EnumValueDescriptorProto* New() const final {
-    return new EnumValueDescriptorProto();
-  }
-
-  EnumValueDescriptorProto* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final {
+  EnumValueDescriptorProto* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final {
     return CreateMaybeMessage<EnumValueDescriptorProto>(arena);
   }
   using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom;
@@ -3128,6 +3104,8 @@
   void SharedDtor();
   void SetCachedSize(int size) const final;
   void InternalSwap(EnumValueDescriptorProto* other);
+
+  private:
   friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
   static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
     return "google.protobuf.EnumValueDescriptorProto";
@@ -3164,7 +3142,7 @@
   template <typename ArgT0 = const std::string&, typename... ArgT>
   void set_name(ArgT0&& arg0, ArgT... args);
   std::string* mutable_name();
-  PROTOBUF_MUST_USE_RESULT std::string* release_name();
+  PROTOBUF_NODISCARD std::string* release_name();
   void set_allocated_name(std::string* name);
   private:
   const std::string& _internal_name() const;
@@ -3179,7 +3157,7 @@
   public:
   void clear_options();
   const ::PROTOBUF_NAMESPACE_ID::EnumValueOptions& options() const;
-  PROTOBUF_MUST_USE_RESULT ::PROTOBUF_NAMESPACE_ID::EnumValueOptions* release_options();
+  PROTOBUF_NODISCARD ::PROTOBUF_NAMESPACE_ID::EnumValueOptions* release_options();
   ::PROTOBUF_NAMESPACE_ID::EnumValueOptions* mutable_options();
   void set_allocated_options(::PROTOBUF_NAMESPACE_ID::EnumValueOptions* options);
   private:
@@ -3300,11 +3278,7 @@
 
   // implements Message ----------------------------------------------
 
-  inline ServiceDescriptorProto* New() const final {
-    return new ServiceDescriptorProto();
-  }
-
-  ServiceDescriptorProto* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final {
+  ServiceDescriptorProto* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final {
     return CreateMaybeMessage<ServiceDescriptorProto>(arena);
   }
   using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom;
@@ -3328,6 +3302,8 @@
   void SharedDtor();
   void SetCachedSize(int size) const final;
   void InternalSwap(ServiceDescriptorProto* other);
+
+  private:
   friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
   static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
     return "google.protobuf.ServiceDescriptorProto";
@@ -3382,7 +3358,7 @@
   template <typename ArgT0 = const std::string&, typename... ArgT>
   void set_name(ArgT0&& arg0, ArgT... args);
   std::string* mutable_name();
-  PROTOBUF_MUST_USE_RESULT std::string* release_name();
+  PROTOBUF_NODISCARD std::string* release_name();
   void set_allocated_name(std::string* name);
   private:
   const std::string& _internal_name() const;
@@ -3397,7 +3373,7 @@
   public:
   void clear_options();
   const ::PROTOBUF_NAMESPACE_ID::ServiceOptions& options() const;
-  PROTOBUF_MUST_USE_RESULT ::PROTOBUF_NAMESPACE_ID::ServiceOptions* release_options();
+  PROTOBUF_NODISCARD ::PROTOBUF_NAMESPACE_ID::ServiceOptions* release_options();
   ::PROTOBUF_NAMESPACE_ID::ServiceOptions* mutable_options();
   void set_allocated_options(::PROTOBUF_NAMESPACE_ID::ServiceOptions* options);
   private:
@@ -3505,11 +3481,7 @@
 
   // implements Message ----------------------------------------------
 
-  inline MethodDescriptorProto* New() const final {
-    return new MethodDescriptorProto();
-  }
-
-  MethodDescriptorProto* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final {
+  MethodDescriptorProto* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final {
     return CreateMaybeMessage<MethodDescriptorProto>(arena);
   }
   using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom;
@@ -3533,6 +3505,8 @@
   void SharedDtor();
   void SetCachedSize(int size) const final;
   void InternalSwap(MethodDescriptorProto* other);
+
+  private:
   friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
   static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
     return "google.protobuf.MethodDescriptorProto";
@@ -3572,7 +3546,7 @@
   template <typename ArgT0 = const std::string&, typename... ArgT>
   void set_name(ArgT0&& arg0, ArgT... args);
   std::string* mutable_name();
-  PROTOBUF_MUST_USE_RESULT std::string* release_name();
+  PROTOBUF_NODISCARD std::string* release_name();
   void set_allocated_name(std::string* name);
   private:
   const std::string& _internal_name() const;
@@ -3590,7 +3564,7 @@
   template <typename ArgT0 = const std::string&, typename... ArgT>
   void set_input_type(ArgT0&& arg0, ArgT... args);
   std::string* mutable_input_type();
-  PROTOBUF_MUST_USE_RESULT std::string* release_input_type();
+  PROTOBUF_NODISCARD std::string* release_input_type();
   void set_allocated_input_type(std::string* input_type);
   private:
   const std::string& _internal_input_type() const;
@@ -3608,7 +3582,7 @@
   template <typename ArgT0 = const std::string&, typename... ArgT>
   void set_output_type(ArgT0&& arg0, ArgT... args);
   std::string* mutable_output_type();
-  PROTOBUF_MUST_USE_RESULT std::string* release_output_type();
+  PROTOBUF_NODISCARD std::string* release_output_type();
   void set_allocated_output_type(std::string* output_type);
   private:
   const std::string& _internal_output_type() const;
@@ -3623,7 +3597,7 @@
   public:
   void clear_options();
   const ::PROTOBUF_NAMESPACE_ID::MethodOptions& options() const;
-  PROTOBUF_MUST_USE_RESULT ::PROTOBUF_NAMESPACE_ID::MethodOptions* release_options();
+  PROTOBUF_NODISCARD ::PROTOBUF_NAMESPACE_ID::MethodOptions* release_options();
   ::PROTOBUF_NAMESPACE_ID::MethodOptions* mutable_options();
   void set_allocated_options(::PROTOBUF_NAMESPACE_ID::MethodOptions* options);
   private:
@@ -3760,11 +3734,7 @@
 
   // implements Message ----------------------------------------------
 
-  inline FileOptions* New() const final {
-    return new FileOptions();
-  }
-
-  FileOptions* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final {
+  FileOptions* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final {
     return CreateMaybeMessage<FileOptions>(arena);
   }
   using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom;
@@ -3788,6 +3758,8 @@
   void SharedDtor();
   void SetCachedSize(int size) const final;
   void InternalSwap(FileOptions* other);
+
+  private:
   friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
   static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
     return "google.protobuf.FileOptions";
@@ -3892,7 +3864,7 @@
   template <typename ArgT0 = const std::string&, typename... ArgT>
   void set_java_package(ArgT0&& arg0, ArgT... args);
   std::string* mutable_java_package();
-  PROTOBUF_MUST_USE_RESULT std::string* release_java_package();
+  PROTOBUF_NODISCARD std::string* release_java_package();
   void set_allocated_java_package(std::string* java_package);
   private:
   const std::string& _internal_java_package() const;
@@ -3910,7 +3882,7 @@
   template <typename ArgT0 = const std::string&, typename... ArgT>
   void set_java_outer_classname(ArgT0&& arg0, ArgT... args);
   std::string* mutable_java_outer_classname();
-  PROTOBUF_MUST_USE_RESULT std::string* release_java_outer_classname();
+  PROTOBUF_NODISCARD std::string* release_java_outer_classname();
   void set_allocated_java_outer_classname(std::string* java_outer_classname);
   private:
   const std::string& _internal_java_outer_classname() const;
@@ -3928,7 +3900,7 @@
   template <typename ArgT0 = const std::string&, typename... ArgT>
   void set_go_package(ArgT0&& arg0, ArgT... args);
   std::string* mutable_go_package();
-  PROTOBUF_MUST_USE_RESULT std::string* release_go_package();
+  PROTOBUF_NODISCARD std::string* release_go_package();
   void set_allocated_go_package(std::string* go_package);
   private:
   const std::string& _internal_go_package() const;
@@ -3946,7 +3918,7 @@
   template <typename ArgT0 = const std::string&, typename... ArgT>
   void set_objc_class_prefix(ArgT0&& arg0, ArgT... args);
   std::string* mutable_objc_class_prefix();
-  PROTOBUF_MUST_USE_RESULT std::string* release_objc_class_prefix();
+  PROTOBUF_NODISCARD std::string* release_objc_class_prefix();
   void set_allocated_objc_class_prefix(std::string* objc_class_prefix);
   private:
   const std::string& _internal_objc_class_prefix() const;
@@ -3964,7 +3936,7 @@
   template <typename ArgT0 = const std::string&, typename... ArgT>
   void set_csharp_namespace(ArgT0&& arg0, ArgT... args);
   std::string* mutable_csharp_namespace();
-  PROTOBUF_MUST_USE_RESULT std::string* release_csharp_namespace();
+  PROTOBUF_NODISCARD std::string* release_csharp_namespace();
   void set_allocated_csharp_namespace(std::string* csharp_namespace);
   private:
   const std::string& _internal_csharp_namespace() const;
@@ -3982,7 +3954,7 @@
   template <typename ArgT0 = const std::string&, typename... ArgT>
   void set_swift_prefix(ArgT0&& arg0, ArgT... args);
   std::string* mutable_swift_prefix();
-  PROTOBUF_MUST_USE_RESULT std::string* release_swift_prefix();
+  PROTOBUF_NODISCARD std::string* release_swift_prefix();
   void set_allocated_swift_prefix(std::string* swift_prefix);
   private:
   const std::string& _internal_swift_prefix() const;
@@ -4000,7 +3972,7 @@
   template <typename ArgT0 = const std::string&, typename... ArgT>
   void set_php_class_prefix(ArgT0&& arg0, ArgT... args);
   std::string* mutable_php_class_prefix();
-  PROTOBUF_MUST_USE_RESULT std::string* release_php_class_prefix();
+  PROTOBUF_NODISCARD std::string* release_php_class_prefix();
   void set_allocated_php_class_prefix(std::string* php_class_prefix);
   private:
   const std::string& _internal_php_class_prefix() const;
@@ -4018,7 +3990,7 @@
   template <typename ArgT0 = const std::string&, typename... ArgT>
   void set_php_namespace(ArgT0&& arg0, ArgT... args);
   std::string* mutable_php_namespace();
-  PROTOBUF_MUST_USE_RESULT std::string* release_php_namespace();
+  PROTOBUF_NODISCARD std::string* release_php_namespace();
   void set_allocated_php_namespace(std::string* php_namespace);
   private:
   const std::string& _internal_php_namespace() const;
@@ -4036,7 +4008,7 @@
   template <typename ArgT0 = const std::string&, typename... ArgT>
   void set_php_metadata_namespace(ArgT0&& arg0, ArgT... args);
   std::string* mutable_php_metadata_namespace();
-  PROTOBUF_MUST_USE_RESULT std::string* release_php_metadata_namespace();
+  PROTOBUF_NODISCARD std::string* release_php_metadata_namespace();
   void set_allocated_php_metadata_namespace(std::string* php_metadata_namespace);
   private:
   const std::string& _internal_php_metadata_namespace() const;
@@ -4054,7 +4026,7 @@
   template <typename ArgT0 = const std::string&, typename... ArgT>
   void set_ruby_package(ArgT0&& arg0, ArgT... args);
   std::string* mutable_ruby_package();
-  PROTOBUF_MUST_USE_RESULT std::string* release_ruby_package();
+  PROTOBUF_NODISCARD std::string* release_ruby_package();
   void set_allocated_ruby_package(std::string* ruby_package);
   private:
   const std::string& _internal_ruby_package() const;
@@ -4281,7 +4253,7 @@
   template <typename _proto_TypeTraits,
             ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
             bool _is_packed>
-  inline PROTOBUF_MUST_USE_RESULT
+  PROTOBUF_NODISCARD inline
       typename _proto_TypeTraits::Singular::MutableType
       ReleaseExtension(
           const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
@@ -4499,11 +4471,7 @@
 
   // implements Message ----------------------------------------------
 
-  inline MessageOptions* New() const final {
-    return new MessageOptions();
-  }
-
-  MessageOptions* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final {
+  MessageOptions* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final {
     return CreateMaybeMessage<MessageOptions>(arena);
   }
   using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom;
@@ -4527,6 +4495,8 @@
   void SharedDtor();
   void SetCachedSize(int size) const final;
   void InternalSwap(MessageOptions* other);
+
+  private:
   friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
   static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
     return "google.protobuf.MessageOptions";
@@ -4714,7 +4684,7 @@
   template <typename _proto_TypeTraits,
             ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
             bool _is_packed>
-  inline PROTOBUF_MUST_USE_RESULT
+  PROTOBUF_NODISCARD inline
       typename _proto_TypeTraits::Singular::MutableType
       ReleaseExtension(
           const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
@@ -4916,11 +4886,7 @@
 
   // implements Message ----------------------------------------------
 
-  inline FieldOptions* New() const final {
-    return new FieldOptions();
-  }
-
-  FieldOptions* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final {
+  FieldOptions* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final {
     return CreateMaybeMessage<FieldOptions>(arena);
   }
   using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom;
@@ -4944,6 +4910,8 @@
   void SharedDtor();
   void SetCachedSize(int size) const final;
   void InternalSwap(FieldOptions* other);
+
+  private:
   friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
   static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
     return "google.protobuf.FieldOptions";
@@ -5223,7 +5191,7 @@
   template <typename _proto_TypeTraits,
             ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
             bool _is_packed>
-  inline PROTOBUF_MUST_USE_RESULT
+  PROTOBUF_NODISCARD inline
       typename _proto_TypeTraits::Singular::MutableType
       ReleaseExtension(
           const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
@@ -5427,11 +5395,7 @@
 
   // implements Message ----------------------------------------------
 
-  inline OneofOptions* New() const final {
-    return new OneofOptions();
-  }
-
-  OneofOptions* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final {
+  OneofOptions* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final {
     return CreateMaybeMessage<OneofOptions>(arena);
   }
   using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom;
@@ -5455,6 +5419,8 @@
   void SharedDtor();
   void SetCachedSize(int size) const final;
   void InternalSwap(OneofOptions* other);
+
+  private:
   friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
   static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
     return "google.protobuf.OneofOptions";
@@ -5586,7 +5552,7 @@
   template <typename _proto_TypeTraits,
             ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
             bool _is_packed>
-  inline PROTOBUF_MUST_USE_RESULT
+  PROTOBUF_NODISCARD inline
       typename _proto_TypeTraits::Singular::MutableType
       ReleaseExtension(
           const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
@@ -5783,11 +5749,7 @@
 
   // implements Message ----------------------------------------------
 
-  inline EnumOptions* New() const final {
-    return new EnumOptions();
-  }
-
-  EnumOptions* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final {
+  EnumOptions* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final {
     return CreateMaybeMessage<EnumOptions>(arena);
   }
   using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom;
@@ -5811,6 +5773,8 @@
   void SharedDtor();
   void SetCachedSize(int size) const final;
   void InternalSwap(EnumOptions* other);
+
+  private:
   friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
   static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
     return "google.protobuf.EnumOptions";
@@ -5970,7 +5934,7 @@
   template <typename _proto_TypeTraits,
             ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
             bool _is_packed>
-  inline PROTOBUF_MUST_USE_RESULT
+  PROTOBUF_NODISCARD inline
       typename _proto_TypeTraits::Singular::MutableType
       ReleaseExtension(
           const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
@@ -6170,11 +6134,7 @@
 
   // implements Message ----------------------------------------------
 
-  inline EnumValueOptions* New() const final {
-    return new EnumValueOptions();
-  }
-
-  EnumValueOptions* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final {
+  EnumValueOptions* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final {
     return CreateMaybeMessage<EnumValueOptions>(arena);
   }
   using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom;
@@ -6198,6 +6158,8 @@
   void SharedDtor();
   void SetCachedSize(int size) const final;
   void InternalSwap(EnumValueOptions* other);
+
+  private:
   friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
   static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
     return "google.protobuf.EnumValueOptions";
@@ -6343,7 +6305,7 @@
   template <typename _proto_TypeTraits,
             ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
             bool _is_packed>
-  inline PROTOBUF_MUST_USE_RESULT
+  PROTOBUF_NODISCARD inline
       typename _proto_TypeTraits::Singular::MutableType
       ReleaseExtension(
           const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
@@ -6542,11 +6504,7 @@
 
   // implements Message ----------------------------------------------
 
-  inline ServiceOptions* New() const final {
-    return new ServiceOptions();
-  }
-
-  ServiceOptions* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final {
+  ServiceOptions* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final {
     return CreateMaybeMessage<ServiceOptions>(arena);
   }
   using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom;
@@ -6570,6 +6528,8 @@
   void SharedDtor();
   void SetCachedSize(int size) const final;
   void InternalSwap(ServiceOptions* other);
+
+  private:
   friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
   static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
     return "google.protobuf.ServiceOptions";
@@ -6715,7 +6675,7 @@
   template <typename _proto_TypeTraits,
             ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
             bool _is_packed>
-  inline PROTOBUF_MUST_USE_RESULT
+  PROTOBUF_NODISCARD inline
       typename _proto_TypeTraits::Singular::MutableType
       ReleaseExtension(
           const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
@@ -6914,11 +6874,7 @@
 
   // implements Message ----------------------------------------------
 
-  inline MethodOptions* New() const final {
-    return new MethodOptions();
-  }
-
-  MethodOptions* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final {
+  MethodOptions* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final {
     return CreateMaybeMessage<MethodOptions>(arena);
   }
   using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom;
@@ -6942,6 +6898,8 @@
   void SharedDtor();
   void SetCachedSize(int size) const final;
   void InternalSwap(MethodOptions* other);
+
+  private:
   friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
   static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
     return "google.protobuf.MethodOptions";
@@ -7133,7 +7091,7 @@
   template <typename _proto_TypeTraits,
             ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
             bool _is_packed>
-  inline PROTOBUF_MUST_USE_RESULT
+  PROTOBUF_NODISCARD inline
       typename _proto_TypeTraits::Singular::MutableType
       ReleaseExtension(
           const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
@@ -7333,11 +7291,7 @@
 
   // implements Message ----------------------------------------------
 
-  inline UninterpretedOption_NamePart* New() const final {
-    return new UninterpretedOption_NamePart();
-  }
-
-  UninterpretedOption_NamePart* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final {
+  UninterpretedOption_NamePart* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final {
     return CreateMaybeMessage<UninterpretedOption_NamePart>(arena);
   }
   using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom;
@@ -7361,6 +7315,8 @@
   void SharedDtor();
   void SetCachedSize(int size) const final;
   void InternalSwap(UninterpretedOption_NamePart* other);
+
+  private:
   friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
   static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
     return "google.protobuf.UninterpretedOption.NamePart";
@@ -7396,7 +7352,7 @@
   template <typename ArgT0 = const std::string&, typename... ArgT>
   void set_name_part(ArgT0&& arg0, ArgT... args);
   std::string* mutable_name_part();
-  PROTOBUF_MUST_USE_RESULT std::string* release_name_part();
+  PROTOBUF_NODISCARD std::string* release_name_part();
   void set_allocated_name_part(std::string* name_part);
   private:
   const std::string& _internal_name_part() const;
@@ -7516,11 +7472,7 @@
 
   // implements Message ----------------------------------------------
 
-  inline UninterpretedOption* New() const final {
-    return new UninterpretedOption();
-  }
-
-  UninterpretedOption* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final {
+  UninterpretedOption* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final {
     return CreateMaybeMessage<UninterpretedOption>(arena);
   }
   using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom;
@@ -7544,6 +7496,8 @@
   void SharedDtor();
   void SetCachedSize(int size) const final;
   void InternalSwap(UninterpretedOption* other);
+
+  private:
   friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
   static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
     return "google.protobuf.UninterpretedOption";
@@ -7604,7 +7558,7 @@
   template <typename ArgT0 = const std::string&, typename... ArgT>
   void set_identifier_value(ArgT0&& arg0, ArgT... args);
   std::string* mutable_identifier_value();
-  PROTOBUF_MUST_USE_RESULT std::string* release_identifier_value();
+  PROTOBUF_NODISCARD std::string* release_identifier_value();
   void set_allocated_identifier_value(std::string* identifier_value);
   private:
   const std::string& _internal_identifier_value() const;
@@ -7622,7 +7576,7 @@
   template <typename ArgT0 = const std::string&, typename... ArgT>
   void set_string_value(ArgT0&& arg0, ArgT... args);
   std::string* mutable_string_value();
-  PROTOBUF_MUST_USE_RESULT std::string* release_string_value();
+  PROTOBUF_NODISCARD std::string* release_string_value();
   void set_allocated_string_value(std::string* string_value);
   private:
   const std::string& _internal_string_value() const;
@@ -7640,7 +7594,7 @@
   template <typename ArgT0 = const std::string&, typename... ArgT>
   void set_aggregate_value(ArgT0&& arg0, ArgT... args);
   std::string* mutable_aggregate_value();
-  PROTOBUF_MUST_USE_RESULT std::string* release_aggregate_value();
+  PROTOBUF_NODISCARD std::string* release_aggregate_value();
   void set_allocated_aggregate_value(std::string* aggregate_value);
   private:
   const std::string& _internal_aggregate_value() const;
@@ -7788,11 +7742,7 @@
 
   // implements Message ----------------------------------------------
 
-  inline SourceCodeInfo_Location* New() const final {
-    return new SourceCodeInfo_Location();
-  }
-
-  SourceCodeInfo_Location* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final {
+  SourceCodeInfo_Location* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final {
     return CreateMaybeMessage<SourceCodeInfo_Location>(arena);
   }
   using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom;
@@ -7816,6 +7766,8 @@
   void SharedDtor();
   void SetCachedSize(int size) const final;
   void InternalSwap(SourceCodeInfo_Location* other);
+
+  private:
   friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
   static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
     return "google.protobuf.SourceCodeInfo.Location";
@@ -7922,7 +7874,7 @@
   template <typename ArgT0 = const std::string&, typename... ArgT>
   void set_leading_comments(ArgT0&& arg0, ArgT... args);
   std::string* mutable_leading_comments();
-  PROTOBUF_MUST_USE_RESULT std::string* release_leading_comments();
+  PROTOBUF_NODISCARD std::string* release_leading_comments();
   void set_allocated_leading_comments(std::string* leading_comments);
   private:
   const std::string& _internal_leading_comments() const;
@@ -7940,7 +7892,7 @@
   template <typename ArgT0 = const std::string&, typename... ArgT>
   void set_trailing_comments(ArgT0&& arg0, ArgT... args);
   std::string* mutable_trailing_comments();
-  PROTOBUF_MUST_USE_RESULT std::string* release_trailing_comments();
+  PROTOBUF_NODISCARD std::string* release_trailing_comments();
   void set_allocated_trailing_comments(std::string* trailing_comments);
   private:
   const std::string& _internal_trailing_comments() const;
@@ -8049,11 +8001,7 @@
 
   // implements Message ----------------------------------------------
 
-  inline SourceCodeInfo* New() const final {
-    return new SourceCodeInfo();
-  }
-
-  SourceCodeInfo* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final {
+  SourceCodeInfo* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final {
     return CreateMaybeMessage<SourceCodeInfo>(arena);
   }
   using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom;
@@ -8077,6 +8025,8 @@
   void SharedDtor();
   void SetCachedSize(int size) const final;
   void InternalSwap(SourceCodeInfo* other);
+
+  private:
   friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
   static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
     return "google.protobuf.SourceCodeInfo";
@@ -8215,11 +8165,7 @@
 
   // implements Message ----------------------------------------------
 
-  inline GeneratedCodeInfo_Annotation* New() const final {
-    return new GeneratedCodeInfo_Annotation();
-  }
-
-  GeneratedCodeInfo_Annotation* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final {
+  GeneratedCodeInfo_Annotation* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final {
     return CreateMaybeMessage<GeneratedCodeInfo_Annotation>(arena);
   }
   using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom;
@@ -8243,6 +8189,8 @@
   void SharedDtor();
   void SetCachedSize(int size) const final;
   void InternalSwap(GeneratedCodeInfo_Annotation* other);
+
+  private:
   friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
   static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
     return "google.protobuf.GeneratedCodeInfo.Annotation";
@@ -8302,7 +8250,7 @@
   template <typename ArgT0 = const std::string&, typename... ArgT>
   void set_source_file(ArgT0&& arg0, ArgT... args);
   std::string* mutable_source_file();
-  PROTOBUF_MUST_USE_RESULT std::string* release_source_file();
+  PROTOBUF_NODISCARD std::string* release_source_file();
   void set_allocated_source_file(std::string* source_file);
   private:
   const std::string& _internal_source_file() const;
@@ -8435,11 +8383,7 @@
 
   // implements Message ----------------------------------------------
 
-  inline GeneratedCodeInfo* New() const final {
-    return new GeneratedCodeInfo();
-  }
-
-  GeneratedCodeInfo* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final {
+  GeneratedCodeInfo* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final {
     return CreateMaybeMessage<GeneratedCodeInfo>(arena);
   }
   using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom;
@@ -8463,6 +8407,8 @@
   void SharedDtor();
   void SetCachedSize(int size) const final;
   void InternalSwap(GeneratedCodeInfo* other);
+
+  private:
   friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
   static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
     return "google.protobuf.GeneratedCodeInfo";
@@ -8618,12 +8564,13 @@
     return nullptr;
   }
   _has_bits_[0] &= ~0x00000001u;
-  return name_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation());
+  auto* p = name_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation());
 #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
   if (name_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) {
     name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
   }
 #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+  return p;
 }
 inline void FileDescriptorProto::set_allocated_name(std::string* name) {
   if (name != nullptr) {
@@ -8686,12 +8633,13 @@
     return nullptr;
   }
   _has_bits_[0] &= ~0x00000002u;
-  return package_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation());
+  auto* p = package_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation());
 #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
   if (package_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) {
     package_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
   }
 #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+  return p;
 }
 inline void FileDescriptorProto::set_allocated_package(std::string* package) {
   if (package != nullptr) {
@@ -9263,12 +9211,13 @@
     return nullptr;
   }
   _has_bits_[0] &= ~0x00000004u;
-  return syntax_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation());
+  auto* p = syntax_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation());
 #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
   if (syntax_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) {
     syntax_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
   }
 #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+  return p;
 }
 inline void FileDescriptorProto::set_allocated_syntax(std::string* syntax) {
   if (syntax != nullptr) {
@@ -9545,12 +9494,13 @@
     return nullptr;
   }
   _has_bits_[0] &= ~0x00000001u;
-  return name_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation());
+  auto* p = name_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation());
 #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
   if (name_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) {
     name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
   }
 #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+  return p;
 }
 inline void DescriptorProto::set_allocated_name(std::string* name) {
   if (name != nullptr) {
@@ -10106,12 +10056,13 @@
     return nullptr;
   }
   _has_bits_[0] &= ~0x00000001u;
-  return name_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation());
+  auto* p = name_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation());
 #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
   if (name_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) {
     name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
   }
 #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+  return p;
 }
 inline void FieldDescriptorProto::set_allocated_name(std::string* name) {
   if (name != nullptr) {
@@ -10260,12 +10211,13 @@
     return nullptr;
   }
   _has_bits_[0] &= ~0x00000004u;
-  return type_name_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation());
+  auto* p = type_name_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation());
 #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
   if (type_name_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) {
     type_name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
   }
 #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+  return p;
 }
 inline void FieldDescriptorProto::set_allocated_type_name(std::string* type_name) {
   if (type_name != nullptr) {
@@ -10328,12 +10280,13 @@
     return nullptr;
   }
   _has_bits_[0] &= ~0x00000002u;
-  return extendee_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation());
+  auto* p = extendee_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation());
 #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
   if (extendee_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) {
     extendee_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
   }
 #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+  return p;
 }
 inline void FieldDescriptorProto::set_allocated_extendee(std::string* extendee) {
   if (extendee != nullptr) {
@@ -10396,12 +10349,13 @@
     return nullptr;
   }
   _has_bits_[0] &= ~0x00000008u;
-  return default_value_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation());
+  auto* p = default_value_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation());
 #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
   if (default_value_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) {
     default_value_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
   }
 #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+  return p;
 }
 inline void FieldDescriptorProto::set_allocated_default_value(std::string* default_value) {
   if (default_value != nullptr) {
@@ -10492,12 +10446,13 @@
     return nullptr;
   }
   _has_bits_[0] &= ~0x00000010u;
-  return json_name_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation());
+  auto* p = json_name_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation());
 #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
   if (json_name_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) {
     json_name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
   }
 #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+  return p;
 }
 inline void FieldDescriptorProto::set_allocated_json_name(std::string* json_name) {
   if (json_name != nullptr) {
@@ -10682,12 +10637,13 @@
     return nullptr;
   }
   _has_bits_[0] &= ~0x00000001u;
-  return name_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation());
+  auto* p = name_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation());
 #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
   if (name_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) {
     name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
   }
 #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+  return p;
 }
 inline void OneofDescriptorProto::set_allocated_name(std::string* name) {
   if (name != nullptr) {
@@ -10904,12 +10860,13 @@
     return nullptr;
   }
   _has_bits_[0] &= ~0x00000001u;
-  return name_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation());
+  auto* p = name_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation());
 #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
   if (name_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) {
     name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
   }
 #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+  return p;
 }
 inline void EnumDescriptorProto::set_allocated_name(std::string* name) {
   if (name != nullptr) {
@@ -11221,12 +11178,13 @@
     return nullptr;
   }
   _has_bits_[0] &= ~0x00000001u;
-  return name_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation());
+  auto* p = name_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation());
 #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
   if (name_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) {
     name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
   }
 #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+  return p;
 }
 inline void EnumValueDescriptorProto::set_allocated_name(std::string* name) {
   if (name != nullptr) {
@@ -11411,12 +11369,13 @@
     return nullptr;
   }
   _has_bits_[0] &= ~0x00000001u;
-  return name_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation());
+  auto* p = name_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation());
 #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
   if (name_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) {
     name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
   }
 #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+  return p;
 }
 inline void ServiceDescriptorProto::set_allocated_name(std::string* name) {
   if (name != nullptr) {
@@ -11613,12 +11572,13 @@
     return nullptr;
   }
   _has_bits_[0] &= ~0x00000001u;
-  return name_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation());
+  auto* p = name_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation());
 #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
   if (name_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) {
     name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
   }
 #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+  return p;
 }
 inline void MethodDescriptorProto::set_allocated_name(std::string* name) {
   if (name != nullptr) {
@@ -11681,12 +11641,13 @@
     return nullptr;
   }
   _has_bits_[0] &= ~0x00000002u;
-  return input_type_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation());
+  auto* p = input_type_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation());
 #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
   if (input_type_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) {
     input_type_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
   }
 #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+  return p;
 }
 inline void MethodDescriptorProto::set_allocated_input_type(std::string* input_type) {
   if (input_type != nullptr) {
@@ -11749,12 +11710,13 @@
     return nullptr;
   }
   _has_bits_[0] &= ~0x00000004u;
-  return output_type_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation());
+  auto* p = output_type_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation());
 #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
   if (output_type_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) {
     output_type_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
   }
 #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+  return p;
 }
 inline void MethodDescriptorProto::set_allocated_output_type(std::string* output_type) {
   if (output_type != nullptr) {
@@ -11967,12 +11929,13 @@
     return nullptr;
   }
   _has_bits_[0] &= ~0x00000001u;
-  return java_package_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation());
+  auto* p = java_package_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation());
 #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
   if (java_package_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) {
     java_package_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
   }
 #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+  return p;
 }
 inline void FileOptions::set_allocated_java_package(std::string* java_package) {
   if (java_package != nullptr) {
@@ -12035,12 +11998,13 @@
     return nullptr;
   }
   _has_bits_[0] &= ~0x00000002u;
-  return java_outer_classname_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation());
+  auto* p = java_outer_classname_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation());
 #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
   if (java_outer_classname_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) {
     java_outer_classname_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
   }
 #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+  return p;
 }
 inline void FileOptions::set_allocated_java_outer_classname(std::string* java_outer_classname) {
   if (java_outer_classname != nullptr) {
@@ -12216,12 +12180,13 @@
     return nullptr;
   }
   _has_bits_[0] &= ~0x00000004u;
-  return go_package_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation());
+  auto* p = go_package_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation());
 #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
   if (go_package_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) {
     go_package_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
   }
 #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+  return p;
 }
 inline void FileOptions::set_allocated_go_package(std::string* go_package) {
   if (go_package != nullptr) {
@@ -12452,12 +12417,13 @@
     return nullptr;
   }
   _has_bits_[0] &= ~0x00000008u;
-  return objc_class_prefix_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation());
+  auto* p = objc_class_prefix_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation());
 #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
   if (objc_class_prefix_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) {
     objc_class_prefix_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
   }
 #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+  return p;
 }
 inline void FileOptions::set_allocated_objc_class_prefix(std::string* objc_class_prefix) {
   if (objc_class_prefix != nullptr) {
@@ -12520,12 +12486,13 @@
     return nullptr;
   }
   _has_bits_[0] &= ~0x00000010u;
-  return csharp_namespace_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation());
+  auto* p = csharp_namespace_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation());
 #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
   if (csharp_namespace_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) {
     csharp_namespace_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
   }
 #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+  return p;
 }
 inline void FileOptions::set_allocated_csharp_namespace(std::string* csharp_namespace) {
   if (csharp_namespace != nullptr) {
@@ -12588,12 +12555,13 @@
     return nullptr;
   }
   _has_bits_[0] &= ~0x00000020u;
-  return swift_prefix_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation());
+  auto* p = swift_prefix_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation());
 #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
   if (swift_prefix_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) {
     swift_prefix_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
   }
 #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+  return p;
 }
 inline void FileOptions::set_allocated_swift_prefix(std::string* swift_prefix) {
   if (swift_prefix != nullptr) {
@@ -12656,12 +12624,13 @@
     return nullptr;
   }
   _has_bits_[0] &= ~0x00000040u;
-  return php_class_prefix_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation());
+  auto* p = php_class_prefix_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation());
 #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
   if (php_class_prefix_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) {
     php_class_prefix_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
   }
 #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+  return p;
 }
 inline void FileOptions::set_allocated_php_class_prefix(std::string* php_class_prefix) {
   if (php_class_prefix != nullptr) {
@@ -12724,12 +12693,13 @@
     return nullptr;
   }
   _has_bits_[0] &= ~0x00000080u;
-  return php_namespace_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation());
+  auto* p = php_namespace_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation());
 #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
   if (php_namespace_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) {
     php_namespace_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
   }
 #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+  return p;
 }
 inline void FileOptions::set_allocated_php_namespace(std::string* php_namespace) {
   if (php_namespace != nullptr) {
@@ -12792,12 +12762,13 @@
     return nullptr;
   }
   _has_bits_[0] &= ~0x00000100u;
-  return php_metadata_namespace_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation());
+  auto* p = php_metadata_namespace_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation());
 #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
   if (php_metadata_namespace_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) {
     php_metadata_namespace_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
   }
 #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+  return p;
 }
 inline void FileOptions::set_allocated_php_metadata_namespace(std::string* php_metadata_namespace) {
   if (php_metadata_namespace != nullptr) {
@@ -12860,12 +12831,13 @@
     return nullptr;
   }
   _has_bits_[0] &= ~0x00000200u;
-  return ruby_package_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation());
+  auto* p = ruby_package_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation());
 #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
   if (ruby_package_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) {
     ruby_package_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
   }
 #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+  return p;
 }
 inline void FileOptions::set_allocated_ruby_package(std::string* ruby_package) {
   if (ruby_package != nullptr) {
@@ -13731,12 +13703,13 @@
     return nullptr;
   }
   _has_bits_[0] &= ~0x00000001u;
-  return name_part_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation());
+  auto* p = name_part_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation());
 #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
   if (name_part_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) {
     name_part_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
   }
 #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+  return p;
 }
 inline void UninterpretedOption_NamePart::set_allocated_name_part(std::string* name_part) {
   if (name_part != nullptr) {
@@ -13871,12 +13844,13 @@
     return nullptr;
   }
   _has_bits_[0] &= ~0x00000001u;
-  return identifier_value_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation());
+  auto* p = identifier_value_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation());
 #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
   if (identifier_value_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) {
     identifier_value_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
   }
 #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+  return p;
 }
 inline void UninterpretedOption::set_allocated_identifier_value(std::string* identifier_value) {
   if (identifier_value != nullptr) {
@@ -14023,12 +13997,13 @@
     return nullptr;
   }
   _has_bits_[0] &= ~0x00000002u;
-  return string_value_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation());
+  auto* p = string_value_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation());
 #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
   if (string_value_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) {
     string_value_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
   }
 #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+  return p;
 }
 inline void UninterpretedOption::set_allocated_string_value(std::string* string_value) {
   if (string_value != nullptr) {
@@ -14091,12 +14066,13 @@
     return nullptr;
   }
   _has_bits_[0] &= ~0x00000004u;
-  return aggregate_value_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation());
+  auto* p = aggregate_value_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation());
 #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
   if (aggregate_value_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) {
     aggregate_value_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
   }
 #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+  return p;
 }
 inline void UninterpretedOption::set_allocated_aggregate_value(std::string* aggregate_value) {
   if (aggregate_value != nullptr) {
@@ -14257,12 +14233,13 @@
     return nullptr;
   }
   _has_bits_[0] &= ~0x00000001u;
-  return leading_comments_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation());
+  auto* p = leading_comments_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation());
 #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
   if (leading_comments_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) {
     leading_comments_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
   }
 #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+  return p;
 }
 inline void SourceCodeInfo_Location::set_allocated_leading_comments(std::string* leading_comments) {
   if (leading_comments != nullptr) {
@@ -14325,12 +14302,13 @@
     return nullptr;
   }
   _has_bits_[0] &= ~0x00000002u;
-  return trailing_comments_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation());
+  auto* p = trailing_comments_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation());
 #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
   if (trailing_comments_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) {
     trailing_comments_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
   }
 #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+  return p;
 }
 inline void SourceCodeInfo_Location::set_allocated_trailing_comments(std::string* trailing_comments) {
   if (trailing_comments != nullptr) {
@@ -14563,12 +14541,13 @@
     return nullptr;
   }
   _has_bits_[0] &= ~0x00000001u;
-  return source_file_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation());
+  auto* p = source_file_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation());
 #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
   if (source_file_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) {
     source_file_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
   }
 #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+  return p;
 }
 inline void GeneratedCodeInfo_Annotation::set_allocated_source_file(std::string* source_file) {
   if (source_file != nullptr) {
diff --git a/src/google/protobuf/descriptor_unittest.cc b/src/google/protobuf/descriptor_unittest.cc
index 634aa99..6202f4f 100644
--- a/src/google/protobuf/descriptor_unittest.cc
+++ b/src/google/protobuf/descriptor_unittest.cc
@@ -776,6 +776,11 @@
     message->CopyJsonNameTo(proto);
   }
 
+  const EnumValueDescriptor* FindValueByNumberCreatingIfUnknown(
+      const EnumDescriptor* desc, int number) {
+    return desc->FindValueByNumberCreatingIfUnknown(number);
+  }
+
   DescriptorPool pool_;
 
   const FileDescriptor* foo_file_;
@@ -2942,6 +2947,8 @@
   EXPECT_EQ("Qux", qux_type->name());
   EXPECT_EQ("corge.Qux", qux_type->full_name());
   EXPECT_TRUE(qux_type->is_placeholder());
+  // Placeholder enum values should not be findable.
+  EXPECT_EQ(qux_type->FindValueByNumber(0), nullptr);
 
   // Placeholder types should not be findable.
   EXPECT_EQ(bar_type_, pool_->FindMessageTypeByName(bar_type_->full_name()));
@@ -3142,6 +3149,7 @@
   const FileDescriptor* file = message->file();
   const FieldDescriptor* field = message->FindFieldByName("field1");
   const OneofDescriptor* oneof = message->FindOneofByName("AnOneof");
+  const FieldDescriptor* map_field = message->FindFieldByName("map_field");
   const EnumDescriptor* enm = message->FindEnumTypeByName("AnEnum");
   // TODO(benjy): Support EnumValue options, once the compiler does.
   const ServiceDescriptor* service =
@@ -3157,6 +3165,8 @@
   EXPECT_EQ(42,  // Check that we get the default for an option we don't set.
             field->options().GetExtension(protobuf_unittest::field_opt2));
   EXPECT_EQ(-99, oneof->options().GetExtension(protobuf_unittest::oneof_opt1));
+  EXPECT_EQ(int64_t{12345},
+            map_field->options().GetExtension(protobuf_unittest::field_opt1));
   EXPECT_EQ(-789, enm->options().GetExtension(protobuf_unittest::enum_opt1));
   EXPECT_EQ(123, enm->value(1)->options().GetExtension(
                      protobuf_unittest::enum_value_opt1));
diff --git a/src/google/protobuf/duration.pb.h b/src/google/protobuf/duration.pb.h
index 4c9ed65..cbf346f 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 < 3017000
+#if PROTOBUF_VERSION < 3018000
 #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 3017003 < PROTOBUF_MIN_PROTOC_VERSION
+#if 3018000 < 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.
@@ -139,11 +139,7 @@
 
   // implements Message ----------------------------------------------
 
-  inline Duration* New() const final {
-    return new Duration();
-  }
-
-  Duration* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final {
+  Duration* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final {
     return CreateMaybeMessage<Duration>(arena);
   }
   using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom;
@@ -167,6 +163,8 @@
   void SharedDtor();
   void SetCachedSize(int size) const final;
   void InternalSwap(Duration* other);
+
+  private:
   friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
   static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
     return "google.protobuf.Duration";
diff --git a/src/google/protobuf/dynamic_message.cc b/src/google/protobuf/dynamic_message.cc
index ba6e007..88c9844 100644
--- a/src/google/protobuf/dynamic_message.cc
+++ b/src/google/protobuf/dynamic_message.cc
@@ -246,7 +246,6 @@
 
   // implements Message ----------------------------------------------
 
-  Message* New() const override;
   Message* New(Arena* arena) const override;
 
   int GetCachedSize() const override;
@@ -355,7 +354,7 @@
   SharedCtor(lock_factory);
 }
 
-void* DynamicMessage::MutableRaw(int i) {
+inline void* DynamicMessage::MutableRaw(int i) {
   return OffsetToPointer(
       OffsetValue(type_info_->offsets[i], type_info_->type->field(i)->type()));
 }
@@ -645,8 +644,6 @@
   }
 }
 
-Message* DynamicMessage::New() const { return New(nullptr); }
-
 Message* DynamicMessage::New(Arena* arena) const {
   if (arena != nullptr) {
     void* new_base = Arena::CreateArray<char>(arena, type_info_->size);
diff --git a/src/google/protobuf/empty.pb.h b/src/google/protobuf/empty.pb.h
index 3aaa2eb..ae15044 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 < 3017000
+#if PROTOBUF_VERSION < 3018000
 #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 3017003 < PROTOBUF_MIN_PROTOC_VERSION
+#if 3018000 < 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.
@@ -139,11 +139,7 @@
 
   // implements Message ----------------------------------------------
 
-  inline Empty* New() const final {
-    return new Empty();
-  }
-
-  Empty* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final {
+  Empty* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final {
     return CreateMaybeMessage<Empty>(arena);
   }
   using ::PROTOBUF_NAMESPACE_ID::internal::ZeroFieldsBase::CopyFrom;
@@ -155,6 +151,8 @@
     ::PROTOBUF_NAMESPACE_ID::internal::ZeroFieldsBase::MergeImpl(this, from);
   }
   public:
+
+  private:
   friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
   static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
     return "google.protobuf.Empty";
diff --git a/src/google/protobuf/explicitly_constructed.h b/src/google/protobuf/explicitly_constructed.h
new file mode 100644
index 0000000..e4a6d07
--- /dev/null
+++ b/src/google/protobuf/explicitly_constructed.h
@@ -0,0 +1,91 @@
+// 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.
+
+#ifndef GOOGLE_PROTOBUF_EXPLICITLY_CONSTRUCTED_H__
+#define GOOGLE_PROTOBUF_EXPLICITLY_CONSTRUCTED_H__
+
+#include <stdint.h>
+
+#include <utility>
+
+#include <google/protobuf/stubs/logging.h>
+#include <google/protobuf/stubs/common.h>
+
+// clang-format off
+#include <google/protobuf/port_def.inc>
+// clang-format on
+
+namespace google {
+namespace protobuf {
+namespace internal {
+
+// Wraps a variable whose constructor and destructor are explicitly
+// called. It is particularly useful for a global variable, without its
+// constructor and destructor run on start and end of the program lifetime.
+// This circumvents the initial construction order fiasco, while keeping
+// the address of the empty string a compile time constant.
+//
+// Pay special attention to the initialization state of the object.
+// 1. The object is "uninitialized" to begin with.
+// 2. Call Construct() or DefaultConstruct() only if the object is
+//    uninitialized. After the call, the object becomes "initialized".
+// 3. Call get() and get_mutable() only if the object is initialized.
+// 4. Call Destruct() only if the object is initialized.
+//    After the call, the object becomes uninitialized.
+template <typename T>
+class ExplicitlyConstructed {
+ public:
+  void DefaultConstruct() { new (&union_) T(); }
+
+  template <typename... Args>
+  void Construct(Args&&... args) {
+    new (&union_) T(std::forward<Args>(args)...);
+  }
+
+  void Destruct() { get_mutable()->~T(); }
+
+  constexpr const T& get() const { return reinterpret_cast<const T&>(union_); }
+  T* get_mutable() { return reinterpret_cast<T*>(&union_); }
+
+ private:
+  union AlignedUnion {
+    alignas(T) char space[sizeof(T)];
+    int64_t align_to_int64;
+    void* align_to_ptr;
+  } union_;
+};
+
+}  // namespace internal
+}  // namespace protobuf
+}  // namespace google
+
+#include <google/protobuf/port_undef.inc>
+
+#endif  // GOOGLE_PROTOBUF_EXPLICITLY_CONSTRUCTED_H__
diff --git a/src/google/protobuf/extension_set.cc b/src/google/protobuf/extension_set.cc
index bbb7ae1..71dc8b4 100644
--- a/src/google/protobuf/extension_set.cc
+++ b/src/google/protobuf/extension_set.cc
@@ -969,7 +969,8 @@
 }
 }  // namespace
 
-void ExtensionSet::MergeFrom(const ExtensionSet& other) {
+void ExtensionSet::MergeFrom(const MessageLite* extendee,
+                             const ExtensionSet& other) {
   if (PROTOBUF_PREDICT_TRUE(!is_large())) {
     if (PROTOBUF_PREDICT_TRUE(!other.is_large())) {
       GrowCapacity(SizeOfUnion(flat_begin(), flat_end(), other.flat_begin(),
@@ -980,12 +981,13 @@
                                other.map_.large->end()));
     }
   }
-  other.ForEach([this, &other](int number, const Extension& ext) {
-    this->InternalExtensionMergeFrom(number, ext, other.arena_);
+  other.ForEach([extendee, this, &other](int number, const Extension& ext) {
+    this->InternalExtensionMergeFrom(extendee, number, ext, other.arena_);
   });
 }
 
-void ExtensionSet::InternalExtensionMergeFrom(int number,
+void ExtensionSet::InternalExtensionMergeFrom(const MessageLite* extendee,
+                                              int number,
                                               const Extension& other_extension,
                                               Arena* other_arena) {
   if (other_extension.is_repeated) {
@@ -1084,6 +1086,7 @@
               extension->lazymessage_value =
                   other_extension.lazymessage_value->New(arena_);
               extension->lazymessage_value->MergeFrom(
+                  GetPrototypeForLazyMessage(extendee, number),
                   *other_extension.lazymessage_value, arena_);
             } else {
               extension->is_lazy = false;
@@ -1099,6 +1102,7 @@
             if (other_extension.is_lazy) {
               if (extension->is_lazy) {
                 extension->lazymessage_value->MergeFrom(
+                    GetPrototypeForLazyMessage(extendee, number),
                     *other_extension.lazymessage_value, arena_);
               } else {
                 extension->message_value->CheckTypeAndMergeFrom(
@@ -1124,23 +1128,23 @@
   }
 }
 
-void ExtensionSet::Swap(ExtensionSet* x) {
+void ExtensionSet::Swap(const MessageLite* extendee, ExtensionSet* other) {
 #ifdef PROTOBUF_FORCE_COPY_IN_SWAP
-  if (GetArena() != nullptr && GetArena() == x->GetArena()) {
+  if (GetArena() != nullptr && GetArena() == other->GetArena()) {
 #else   // PROTOBUF_FORCE_COPY_IN_SWAP
-  if (GetArena() == x->GetArena()) {
+  if (GetArena() == other->GetArena()) {
 #endif  // !PROTOBUF_FORCE_COPY_IN_SWAP
-    InternalSwap(x);
+    InternalSwap(other);
   } else {
     // TODO(cfallin, rohananil): We maybe able to optimize a case where we are
     // swapping from heap to arena-allocated extension set, by just Own()'ing
     // the extensions.
     ExtensionSet extension_set;
-    extension_set.MergeFrom(*x);
-    x->Clear();
-    x->MergeFrom(*this);
+    extension_set.MergeFrom(extendee, *other);
+    other->Clear();
+    other->MergeFrom(extendee, *this);
     Clear();
-    MergeFrom(extension_set);
+    MergeFrom(extendee, extension_set);
   }
 }
 
@@ -1152,7 +1156,8 @@
   swap(map_, other->map_);
 }
 
-void ExtensionSet::SwapExtension(ExtensionSet* other, int number) {
+void ExtensionSet::SwapExtension(const MessageLite* extendee,
+                                 ExtensionSet* other, int number) {
   if (this == other) return;
 
   if (GetArena() == other->GetArena()) {
@@ -1172,19 +1177,22 @@
     // We do it this way to reuse the copy-across-arenas logic already
     // implemented in ExtensionSet's MergeFrom.
     ExtensionSet temp;
-    temp.InternalExtensionMergeFrom(number, *other_ext, other->GetArena());
+    temp.InternalExtensionMergeFrom(extendee, number, *other_ext,
+                                    other->GetArena());
     Extension* temp_ext = temp.FindOrNull(number);
 
     other_ext->Clear();
-    other->InternalExtensionMergeFrom(number, *this_ext, this->GetArena());
+    other->InternalExtensionMergeFrom(extendee, number, *this_ext,
+                                      this->GetArena());
     this_ext->Clear();
-    InternalExtensionMergeFrom(number, *temp_ext, temp.GetArena());
+    InternalExtensionMergeFrom(extendee, number, *temp_ext, temp.GetArena());
   } else if (this_ext == nullptr) {
-    InternalExtensionMergeFrom(number, *other_ext, other->GetArena());
+    InternalExtensionMergeFrom(extendee, number, *other_ext, other->GetArena());
     if (other->GetArena() == nullptr) other_ext->Free();
     other->Erase(number);
   } else {
-    other->InternalExtensionMergeFrom(number, *this_ext, this->GetArena());
+    other->InternalExtensionMergeFrom(extendee, number, *this_ext,
+                                      this->GetArena());
     if (GetArena() == nullptr) this_ext->Free();
     Erase(number);
   }
diff --git a/src/google/protobuf/extension_set.h b/src/google/protobuf/extension_set.h
index 1505020..2c52fe7 100644
--- a/src/google/protobuf/extension_set.h
+++ b/src/google/protobuf/extension_set.h
@@ -289,12 +289,12 @@
   void UnsafeArenaSetAllocatedMessage(int number, FieldType type,
                                       const FieldDescriptor* descriptor,
                                       MessageLite* message);
-  PROTOBUF_MUST_USE_RESULT MessageLite* ReleaseMessage(
-      int number, const MessageLite& prototype);
+  PROTOBUF_NODISCARD MessageLite* ReleaseMessage(int number,
+                                                 const MessageLite& prototype);
   MessageLite* UnsafeArenaReleaseMessage(int number,
                                          const MessageLite& prototype);
 
-  PROTOBUF_MUST_USE_RESULT MessageLite* ReleaseMessage(
+  PROTOBUF_NODISCARD MessageLite* ReleaseMessage(
       const FieldDescriptor* descriptor, MessageFactory* factory);
   MessageLite* UnsafeArenaReleaseMessage(const FieldDescriptor* descriptor,
                                          MessageFactory* factory);
@@ -364,7 +364,7 @@
 #undef desc
 
   void RemoveLast(int number);
-  PROTOBUF_MUST_USE_RESULT MessageLite* ReleaseLast(int number);
+  PROTOBUF_NODISCARD MessageLite* ReleaseLast(int number);
   MessageLite* UnsafeArenaReleaseLast(int number);
   void SwapElements(int number, int index1, int index2);
 
@@ -378,10 +378,11 @@
   // class, but providing them here helps keep the generated code size down.
 
   void Clear();
-  void MergeFrom(const ExtensionSet& other);
-  void Swap(ExtensionSet* other);
+  void MergeFrom(const MessageLite* extendee, const ExtensionSet& other);
+  void Swap(const MessageLite* extendee, ExtensionSet* other);
   void InternalSwap(ExtensionSet* other);
-  void SwapExtension(ExtensionSet* other, int number);
+  void SwapExtension(const MessageLite* extendee, ExtensionSet* other,
+                     int number);
   void UnsafeShallowSwapExtension(ExtensionSet* other, int number);
   bool IsInitialized() const;
 
@@ -583,7 +584,7 @@
     virtual void SetAllocatedMessage(MessageLite* message, Arena* arena) = 0;
     virtual void UnsafeArenaSetAllocatedMessage(MessageLite* message,
                                                 Arena* arena) = 0;
-    virtual PROTOBUF_MUST_USE_RESULT MessageLite* ReleaseMessage(
+    PROTOBUF_NODISCARD virtual MessageLite* ReleaseMessage(
         const MessageLite& prototype, Arena* arena) = 0;
     virtual MessageLite* UnsafeArenaReleaseMessage(const MessageLite& prototype,
                                                    Arena* arena) = 0;
@@ -595,13 +596,15 @@
     virtual size_t ByteSizeLong() const = 0;
     virtual size_t SpaceUsedLong() const = 0;
 
-    virtual void MergeFrom(const LazyMessageExtension& other, Arena* arena) = 0;
+    virtual void MergeFrom(const MessageLite* prototype,
+                           const LazyMessageExtension& other, Arena* arena) = 0;
     virtual void MergeFromMessage(const MessageLite& msg, Arena* arena) = 0;
     virtual void Clear() = 0;
 
     virtual bool ReadMessage(const MessageLite& prototype,
                              io::CodedInputStream* input) = 0;
-    virtual const char* _InternalParse(const char* ptr, ParseContext* ctx) = 0;
+    virtual const char* _InternalParse(const Message& prototype, Arena* arena,
+                                       const char* ptr, ParseContext* ctx) = 0;
     virtual uint8_t* WriteMessageToArray(
         const MessageLite* prototype, int number, uint8_t* target,
         io::EpsCopyOutputStream* stream) const = 0;
@@ -770,7 +773,8 @@
   }
 
   // Merges existing Extension from other_extension
-  void InternalExtensionMergeFrom(int number, const Extension& other_extension,
+  void InternalExtensionMergeFrom(const MessageLite* extendee, int number,
+                                  const Extension& other_extension,
                                   Arena* other_arena);
 
   // Returns true and fills field_number and extension if extension is found.
@@ -1374,8 +1378,8 @@
                                              ExtensionSet* set) {
     set->UnsafeArenaSetAllocatedMessage(number, field_type, nullptr, message);
   }
-  static inline PROTOBUF_MUST_USE_RESULT MutableType
-  Release(int number, FieldType /* field_type */, ExtensionSet* set) {
+  PROTOBUF_NODISCARD static inline MutableType Release(
+      int number, FieldType /* field_type */, ExtensionSet* set) {
     return static_cast<Type*>(
         set->ReleaseMessage(number, Type::default_instance()));
   }
diff --git a/src/google/protobuf/field_mask.pb.h b/src/google/protobuf/field_mask.pb.h
index 619f9a3..fa3b336 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 < 3017000
+#if PROTOBUF_VERSION < 3018000
 #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 3017003 < PROTOBUF_MIN_PROTOC_VERSION
+#if 3018000 < 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.
@@ -139,11 +139,7 @@
 
   // implements Message ----------------------------------------------
 
-  inline FieldMask* New() const final {
-    return new FieldMask();
-  }
-
-  FieldMask* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final {
+  FieldMask* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final {
     return CreateMaybeMessage<FieldMask>(arena);
   }
   using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom;
@@ -167,6 +163,8 @@
   void SharedDtor();
   void SetCachedSize(int size) const final;
   void InternalSwap(FieldMask* other);
+
+  private:
   friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
   static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
     return "google.protobuf.FieldMask";
diff --git a/src/google/protobuf/generated_message_reflection.cc b/src/google/protobuf/generated_message_reflection.cc
index 3582dcc..9004033 100644
--- a/src/google/protobuf/generated_message_reflection.cc
+++ b/src/google/protobuf/generated_message_reflection.cc
@@ -995,6 +995,8 @@
   GOOGLE_DCHECK(!unsafe_shallow_swap || message1->GetArenaForAllocation() ==
                                      message2->GetArenaForAllocation());
 
+  const Message* prototype =
+      message_factory_->GetPrototype(message1->GetDescriptor());
   for (const auto* field : fields) {
     CheckInvalidAccess(schema_, field);
     if (field->is_extension()) {
@@ -1003,7 +1005,7 @@
             MutableExtensionSet(message2), field->number());
       } else {
         MutableExtensionSet(message1)->SwapExtension(
-            MutableExtensionSet(message2), field->number());
+            prototype, MutableExtensionSet(message2), field->number());
       }
     } else {
       if (schema_.InRealOneof(field)) {
diff --git a/src/google/protobuf/generated_message_table_driven_lite.h b/src/google/protobuf/generated_message_table_driven_lite.h
index 780753b..a05afc0 100644
--- a/src/google/protobuf/generated_message_table_driven_lite.h
+++ b/src/google/protobuf/generated_message_table_driven_lite.h
@@ -343,9 +343,6 @@
   typedef MessageLite Type;
   typedef MessageLite WeakType;
   static Arena* GetArena(Type* t) { return t->GetArena(); }
-  static void* GetMaybeArenaPointer(Type* t) {
-    return t->GetMaybeArenaPointer();
-  }
   static inline Type* NewFromPrototype(const Type* prototype,
                                        Arena* arena = nullptr) {
     return prototype->New(arena);
diff --git a/src/google/protobuf/implicit_weak_message.h b/src/google/protobuf/implicit_weak_message.h
index 5456c52..5db8b9c 100644
--- a/src/google/protobuf/implicit_weak_message.h
+++ b/src/google/protobuf/implicit_weak_message.h
@@ -63,7 +63,6 @@
 
   std::string GetTypeName() const override { return ""; }
 
-  MessageLite* New() const override { return new ImplicitWeakMessage; }
   MessageLite* New(Arena* arena) const override {
     return Arena::CreateMessage<ImplicitWeakMessage>(arena);
   }
@@ -115,9 +114,6 @@
   static inline Arena* GetArena(MessageLite* value) {
     return value->GetArena();
   }
-  static inline void* GetMaybeArenaPointer(MessageLite* value) {
-    return value->GetArena();
-  }
   static inline void Clear(MessageLite* value) { value->Clear(); }
   static void Merge(const MessageLite& from, MessageLite* to) {
     to->CheckTypeAndMergeFrom(from);
diff --git a/src/google/protobuf/inlined_string_field.h b/src/google/protobuf/inlined_string_field.h
index 759ae26..1fe639f 100644
--- a/src/google/protobuf/inlined_string_field.h
+++ b/src/google/protobuf/inlined_string_field.h
@@ -202,9 +202,9 @@
   // Own()'d by any arena. If the field is not set, this returns nullptr. The
   // caller retains ownership. Clears this field back to nullptr state. Used to
   // implement release_<field>() methods on generated classes.
-  PROTOBUF_MUST_USE_RESULT std::string* Release(
-      const std::string* default_value, Arena* arena, bool donated);
-  PROTOBUF_MUST_USE_RESULT std::string* ReleaseNonDefault(
+  PROTOBUF_NODISCARD std::string* Release(const std::string* default_value,
+                                          Arena* arena, bool donated);
+  PROTOBUF_NODISCARD std::string* ReleaseNonDefault(
       const std::string* default_value, Arena* arena);
   std::string* ReleaseNonDefaultNoArena(const std::string* default_value);
 
diff --git a/src/google/protobuf/io/coded_stream.h b/src/google/protobuf/io/coded_stream.h
index 13674e4..67d6362 100644
--- a/src/google/protobuf/io/coded_stream.h
+++ b/src/google/protobuf/io/coded_stream.h
@@ -242,10 +242,10 @@
   // responsible for ensuring that the buffer has sufficient space.
   // Read a 32-bit little-endian integer.
   static const uint8_t* ReadLittleEndian32FromArray(const uint8_t* buffer,
-                                                  uint32_t* value);
+                                                    uint32_t* value);
   // Read a 64-bit little-endian integer.
   static const uint8_t* ReadLittleEndian64FromArray(const uint8_t* buffer,
-                                                  uint64_t* value);
+                                                    uint64_t* value);
 
   // Read an unsigned integer with Varint encoding, truncating to 32 bits.
   // Reading a 32-bit value is equivalent to reading a 64-bit one and casting
@@ -315,7 +315,7 @@
   // was not.
   PROTOBUF_ALWAYS_INLINE
   static const uint8_t* ExpectTagFromArray(const uint8_t* buffer,
-                                         uint32_t expected);
+                                           uint32_t expected);
 
   // Usually returns true if no more bytes can be read.  Always returns false
   // if more bytes can be read.  If ExpectAtEnd() returns true, a subsequent
@@ -688,7 +688,7 @@
   // After this it's guaranteed you can safely write kSlopBytes to ptr. This
   // will never fail! The underlying stream can produce an error. Use HadError
   // to check for errors.
-  PROTOBUF_MUST_USE_RESULT uint8_t* EnsureSpace(uint8_t* ptr) {
+  PROTOBUF_NODISCARD uint8_t* EnsureSpace(uint8_t* ptr) {
     if (PROTOBUF_PREDICT_FALSE(ptr >= end_)) {
       return EnsureSpaceFallback(ptr);
     }
@@ -715,7 +715,8 @@
   }
 
 
-  uint8_t* WriteStringMaybeAliased(uint32_t num, const std::string& s, uint8_t* ptr) {
+  uint8_t* WriteStringMaybeAliased(uint32_t num, const std::string& s,
+                                   uint8_t* ptr) {
     std::ptrdiff_t size = s.size();
     if (PROTOBUF_PREDICT_FALSE(
             size >= 128 || end_ - ptr + 16 - TagSize(num << 3) - 1 < size)) {
@@ -726,13 +727,14 @@
     std::memcpy(ptr, s.data(), size);
     return ptr + size;
   }
-  uint8_t* WriteBytesMaybeAliased(uint32_t num, const std::string& s, uint8_t* ptr) {
+  uint8_t* WriteBytesMaybeAliased(uint32_t num, const std::string& s,
+                                  uint8_t* ptr) {
     return WriteStringMaybeAliased(num, s, ptr);
   }
 
   template <typename T>
   PROTOBUF_ALWAYS_INLINE uint8_t* WriteString(uint32_t num, const T& s,
-                                            uint8_t* ptr) {
+                                              uint8_t* ptr) {
     std::ptrdiff_t size = s.size();
     if (PROTOBUF_PREDICT_FALSE(
             size >= 128 || end_ - ptr + 16 - TagSize(num << 3) - 1 < size)) {
@@ -749,44 +751,44 @@
   }
 
   template <typename T>
-  PROTOBUF_ALWAYS_INLINE uint8_t* WriteInt32Packed(int num, const T& r, int size,
-                                                 uint8_t* ptr) {
+  PROTOBUF_ALWAYS_INLINE uint8_t* WriteInt32Packed(int num, const T& r,
+                                                   int size, uint8_t* ptr) {
     return WriteVarintPacked(num, r, size, ptr, Encode64);
   }
   template <typename T>
-  PROTOBUF_ALWAYS_INLINE uint8_t* WriteUInt32Packed(int num, const T& r, int size,
-                                                  uint8_t* ptr) {
+  PROTOBUF_ALWAYS_INLINE uint8_t* WriteUInt32Packed(int num, const T& r,
+                                                    int size, uint8_t* ptr) {
     return WriteVarintPacked(num, r, size, ptr, Encode32);
   }
   template <typename T>
-  PROTOBUF_ALWAYS_INLINE uint8_t* WriteSInt32Packed(int num, const T& r, int size,
-                                                  uint8_t* ptr) {
+  PROTOBUF_ALWAYS_INLINE uint8_t* WriteSInt32Packed(int num, const T& r,
+                                                    int size, uint8_t* ptr) {
     return WriteVarintPacked(num, r, size, ptr, ZigZagEncode32);
   }
   template <typename T>
-  PROTOBUF_ALWAYS_INLINE uint8_t* WriteInt64Packed(int num, const T& r, int size,
-                                                 uint8_t* ptr) {
+  PROTOBUF_ALWAYS_INLINE uint8_t* WriteInt64Packed(int num, const T& r,
+                                                   int size, uint8_t* ptr) {
     return WriteVarintPacked(num, r, size, ptr, Encode64);
   }
   template <typename T>
-  PROTOBUF_ALWAYS_INLINE uint8_t* WriteUInt64Packed(int num, const T& r, int size,
-                                                  uint8_t* ptr) {
+  PROTOBUF_ALWAYS_INLINE uint8_t* WriteUInt64Packed(int num, const T& r,
+                                                    int size, uint8_t* ptr) {
     return WriteVarintPacked(num, r, size, ptr, Encode64);
   }
   template <typename T>
-  PROTOBUF_ALWAYS_INLINE uint8_t* WriteSInt64Packed(int num, const T& r, int size,
-                                                  uint8_t* ptr) {
+  PROTOBUF_ALWAYS_INLINE uint8_t* WriteSInt64Packed(int num, const T& r,
+                                                    int size, uint8_t* ptr) {
     return WriteVarintPacked(num, r, size, ptr, ZigZagEncode64);
   }
   template <typename T>
   PROTOBUF_ALWAYS_INLINE uint8_t* WriteEnumPacked(int num, const T& r, int size,
-                                                uint8_t* ptr) {
+                                                  uint8_t* ptr) {
     return WriteVarintPacked(num, r, size, ptr, Encode64);
   }
 
   template <typename T>
   PROTOBUF_ALWAYS_INLINE uint8_t* WriteFixedPacked(int num, const T& r,
-                                                 uint8_t* ptr) {
+                                                   uint8_t* ptr) {
     ptr = EnsureSpace(ptr);
     constexpr auto element_size = sizeof(typename T::value_type);
     auto size = r.size() * element_size;
@@ -857,13 +859,14 @@
                                : 5;
   }
 
-  PROTOBUF_ALWAYS_INLINE uint8_t* WriteTag(uint32_t num, uint32_t wt, uint8_t* ptr) {
+  PROTOBUF_ALWAYS_INLINE uint8_t* WriteTag(uint32_t num, uint32_t wt,
+                                           uint8_t* ptr) {
     GOOGLE_DCHECK(ptr < end_);  // NOLINT
     return UnsafeVarint((num << 3) | wt, ptr);
   }
 
   PROTOBUF_ALWAYS_INLINE uint8_t* WriteLengthDelim(int num, uint32_t size,
-                                                 uint8_t* ptr) {
+                                                   uint8_t* ptr) {
     ptr = WriteTag(num, 2, ptr);
     return UnsafeWriteSize(size, ptr);
   }
@@ -873,12 +876,13 @@
   uint8_t* WriteAliasedRaw(const void* data, int size, uint8_t* ptr);
 
   uint8_t* WriteStringMaybeAliasedOutline(uint32_t num, const std::string& s,
-                                        uint8_t* ptr);
+                                          uint8_t* ptr);
   uint8_t* WriteStringOutline(uint32_t num, const std::string& s, uint8_t* ptr);
 
   template <typename T, typename E>
-  PROTOBUF_ALWAYS_INLINE uint8_t* WriteVarintPacked(int num, const T& r, int size,
-                                                  uint8_t* ptr, const E& encode) {
+  PROTOBUF_ALWAYS_INLINE uint8_t* WriteVarintPacked(int num, const T& r,
+                                                    int size, uint8_t* ptr,
+                                                    const E& encode) {
     ptr = EnsureSpace(ptr);
     ptr = WriteLengthDelim(num, size, ptr);
     auto it = r.data();
@@ -926,7 +930,7 @@
   }
 
   PROTOBUF_ALWAYS_INLINE static uint8_t* UnsafeWriteSize(uint32_t value,
-                                                       uint8_t* ptr) {
+                                                         uint8_t* ptr) {
     while (PROTOBUF_PREDICT_FALSE(value >= 0x80)) {
       *ptr = static_cast<uint8_t>(value | 0x80);
       value >>= 7;
@@ -977,14 +981,14 @@
 
 template <>
 inline uint8_t* EpsCopyOutputStream::WriteRawLittleEndian<1>(const void* data,
-                                                           int size,
-                                                           uint8_t* ptr) {
+                                                             int size,
+                                                             uint8_t* ptr) {
   return WriteRaw(data, size, ptr);
 }
 template <>
 inline uint8_t* EpsCopyOutputStream::WriteRawLittleEndian<4>(const void* data,
-                                                           int size,
-                                                           uint8_t* ptr) {
+                                                             int size,
+                                                             uint8_t* ptr) {
 #ifdef PROTOBUF_LITTLE_ENDIAN
   return WriteRaw(data, size, ptr);
 #else
@@ -993,8 +997,8 @@
 }
 template <>
 inline uint8_t* EpsCopyOutputStream::WriteRawLittleEndian<8>(const void* data,
-                                                           int size,
-                                                           uint8_t* ptr) {
+                                                             int size,
+                                                             uint8_t* ptr) {
 #ifdef PROTOBUF_LITTLE_ENDIAN
   return WriteRaw(data, size, ptr);
 #else
@@ -1118,7 +1122,8 @@
   // copy loops. Since this gets called by every field with string or bytes
   // type, inlining may lead to a significant amount of code bloat, with only a
   // minor performance gain.
-  static uint8_t* WriteRawToArray(const void* buffer, int size, uint8_t* target);
+  static uint8_t* WriteRawToArray(const void* buffer, int size,
+                                  uint8_t* target);
 
   // Equivalent to WriteRaw(str.data(), str.size()).
   void WriteString(const std::string& str);
@@ -1126,7 +1131,7 @@
   static uint8_t* WriteStringToArray(const std::string& str, uint8_t* target);
   // Write the varint-encoded size of str followed by str.
   static uint8_t* WriteStringWithSizeToArray(const std::string& str,
-                                           uint8_t* target);
+                                             uint8_t* target);
 
 
   // Write a 32-bit little-endian integer.
@@ -1150,9 +1155,10 @@
   void WriteVarint32(uint32_t value);
   // Like WriteVarint32()  but writing directly to the target array.
   static uint8_t* WriteVarint32ToArray(uint32_t value, uint8_t* target);
-  // Like WriteVarint32()  but writing directly to the target array, and with the
-  // less common-case paths being out of line rather than inlined.
-  static uint8_t* WriteVarint32ToArrayOutOfLine(uint32_t value, uint8_t* target);
+  // Like WriteVarint32()  but writing directly to the target array, and with
+  // the less common-case paths being out of line rather than inlined.
+  static uint8_t* WriteVarint32ToArrayOutOfLine(uint32_t value,
+                                                uint8_t* target);
   // Write an unsigned integer with Varint encoding.
   void WriteVarint64(uint64_t value);
   // Like WriteVarint64()  but writing directly to the target array.
@@ -1162,7 +1168,8 @@
   // in which case it must be sign-extended to a full 10 bytes.
   void WriteVarint32SignExtended(int32_t value);
   // Like WriteVarint32SignExtended()  but writing directly to the target array.
-  static uint8_t* WriteVarint32SignExtendedToArray(int32_t value, uint8_t* target);
+  static uint8_t* WriteVarint32SignExtendedToArray(int32_t value,
+                                                   uint8_t* target);
 
   // This is identical to WriteVarint32(), but optimized for writing tags.
   // In particular, if the input is a compile-time constant, this method
@@ -1273,7 +1280,8 @@
     default_serialization_deterministic_.store(true, std::memory_order_relaxed);
   }
   // REQUIRES: value >= 0x80, and that (value & 7f) has been written to *target.
-  static uint8_t* WriteVarint32ToArrayOutOfLineHelper(uint32_t value, uint8_t* target);
+  static uint8_t* WriteVarint32ToArrayOutOfLineHelper(uint32_t value,
+                                                      uint8_t* target);
   GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(CodedOutputStream);
 };
 
@@ -1342,13 +1350,13 @@
   return buffer + sizeof(*value);
 #else
   uint32_t part0 = (static_cast<uint32_t>(buffer[0])) |
-                 (static_cast<uint32_t>(buffer[1]) << 8) |
-                 (static_cast<uint32_t>(buffer[2]) << 16) |
-                 (static_cast<uint32_t>(buffer[3]) << 24);
+                   (static_cast<uint32_t>(buffer[1]) << 8) |
+                   (static_cast<uint32_t>(buffer[2]) << 16) |
+                   (static_cast<uint32_t>(buffer[3]) << 24);
   uint32_t part1 = (static_cast<uint32_t>(buffer[4])) |
-                 (static_cast<uint32_t>(buffer[5]) << 8) |
-                 (static_cast<uint32_t>(buffer[6]) << 16) |
-                 (static_cast<uint32_t>(buffer[7]) << 24);
+                   (static_cast<uint32_t>(buffer[5]) << 8) |
+                   (static_cast<uint32_t>(buffer[6]) << 16) |
+                   (static_cast<uint32_t>(buffer[7]) << 24);
   *value = static_cast<uint64_t>(part0) | (static_cast<uint64_t>(part1) << 32);
   return buffer + sizeof(*value);
 #endif
@@ -1465,8 +1473,8 @@
   }
 }
 
-inline const uint8_t* CodedInputStream::ExpectTagFromArray(const uint8_t* buffer,
-                                                         uint32_t expected) {
+inline const uint8_t* CodedInputStream::ExpectTagFromArray(
+    const uint8_t* buffer, uint32_t expected) {
   if (expected < (1 << 7)) {
     if (buffer[0] == expected) {
       return buffer + 1;
@@ -1600,7 +1608,7 @@
 }
 
 inline uint8_t* CodedOutputStream::WriteVarint32ToArray(uint32_t value,
-                                                      uint8_t* target) {
+                                                        uint8_t* target) {
   return EpsCopyOutputStream::UnsafeVarint(value, target);
 }
 
@@ -1615,7 +1623,7 @@
 }
 
 inline uint8_t* CodedOutputStream::WriteVarint64ToArray(uint64_t value,
-                                                      uint8_t* target) {
+                                                        uint8_t* target) {
   return EpsCopyOutputStream::UnsafeVarint(value, target);
 }
 
@@ -1629,7 +1637,7 @@
 }
 
 inline uint8_t* CodedOutputStream::WriteLittleEndian32ToArray(uint32_t value,
-                                                            uint8_t* target) {
+                                                              uint8_t* target) {
 #if defined(PROTOBUF_LITTLE_ENDIAN)
   memcpy(target, &value, sizeof(value));
 #else
@@ -1642,7 +1650,7 @@
 }
 
 inline uint8_t* CodedOutputStream::WriteLittleEndian64ToArray(uint64_t value,
-                                                            uint8_t* target) {
+                                                              uint8_t* target) {
 #if defined(PROTOBUF_LITTLE_ENDIAN)
   memcpy(target, &value, sizeof(value));
 #else
@@ -1716,7 +1724,8 @@
   return VarintSize64(static_cast<uint64_t>(int64_t{value}));
 }
 
-inline size_t CodedOutputStream::VarintSize32SignExtendedPlusOne(int32_t value) {
+inline size_t CodedOutputStream::VarintSize32SignExtendedPlusOne(
+    int32_t value) {
   return VarintSize64PlusOne(static_cast<uint64_t>(int64_t{value}));
 }
 
@@ -1730,13 +1739,13 @@
 }
 
 inline uint8_t* CodedOutputStream::WriteRawToArray(const void* data, int size,
-                                                 uint8_t* target) {
+                                                   uint8_t* target) {
   memcpy(target, data, size);
   return target + size;
 }
 
 inline uint8_t* CodedOutputStream::WriteStringToArray(const std::string& str,
-                                                    uint8_t* target) {
+                                                      uint8_t* target) {
   return WriteRawToArray(str.data(), static_cast<int>(str.size()), target);
 }
 
diff --git a/src/google/protobuf/map_entry_lite.h b/src/google/protobuf/map_entry_lite.h
index 082a1ee..34b185b 100644
--- a/src/google/protobuf/map_entry_lite.h
+++ b/src/google/protobuf/map_entry_lite.h
@@ -286,11 +286,6 @@
     return ValueTypeHandler::IsInitialized(value_);
   }
 
-  Base* New() const override {
-    Derived* entry = new Derived;
-    return entry;
-  }
-
   Base* New(Arena* arena) const override {
     Derived* entry = Arena::CreateMessage<Derived>(arena);
     return entry;
diff --git a/src/google/protobuf/message.h b/src/google/protobuf/message.h
index 90b4e49..a086945 100644
--- a/src/google/protobuf/message.h
+++ b/src/google/protobuf/message.h
@@ -158,7 +158,7 @@
 class MapFieldBase;
 class SwapFieldHelper;
 class CachedSize;
-}
+}  // namespace internal
 class UnknownFieldSet;  // unknown_field_set.h
 namespace io {
 class ZeroCopyInputStream;   // zero_copy_stream.h
@@ -169,7 +169,7 @@
 namespace python {
 class MapReflectionFriend;  // scalar_map_container.h
 class MessageReflectionFriend;
-}
+}  // namespace python
 namespace expr {
 class CelMapReflectionFriend;  // field_backed_map_impl.cc
 }
@@ -244,18 +244,11 @@
   // Construct a new instance of the same type.  Ownership is passed to the
   // caller.  (This is also defined in MessageLite, but is defined again here
   // for return-type covariance.)
-  Message* New() const override = 0;
+  Message* New() const { return New(nullptr); }
 
   // Construct a new instance on the arena. Ownership is passed to the caller
-  // if arena is a nullptr. Default implementation allows for API compatibility
-  // during the Arena transition.
-  Message* New(Arena* arena) const override {
-    Message* message = New();
-    if (arena != nullptr) {
-      arena->Own(message);
-    }
-    return message;
-  }
+  // if arena is a nullptr.
+  Message* New(Arena* arena) const override = 0;
 
   // Make this message into a copy of the given message.  The given message
   // must have the same descriptor, but need not necessarily be the same class.
@@ -507,8 +500,8 @@
   void RemoveLast(Message* message, const FieldDescriptor* field) const;
   // Removes the last element of a repeated message field, and returns the
   // pointer to the caller.  Caller takes ownership of the returned pointer.
-  PROTOBUF_MUST_USE_RESULT Message* ReleaseLast(
-      Message* message, const FieldDescriptor* field) const;
+  PROTOBUF_NODISCARD Message* ReleaseLast(Message* message,
+                                          const FieldDescriptor* field) const;
 
   // Similar to ReleaseLast() without internal safety and ownershp checks. This
   // method should only be used when the objects are on the same arena or paired
@@ -662,7 +655,7 @@
   // If the field existed (HasField() is true), then the returned pointer will
   // be the same as the pointer returned by MutableMessage().
   // This function has the same effect as ClearField().
-  PROTOBUF_MUST_USE_RESULT Message* ReleaseMessage(
+  PROTOBUF_NODISCARD Message* ReleaseMessage(
       Message* message, const FieldDescriptor* field,
       MessageFactory* factory = nullptr) const;
 
diff --git a/src/google/protobuf/message_lite.cc b/src/google/protobuf/message_lite.cc
index e4cb649..aef6621 100644
--- a/src/google/protobuf/message_lite.cc
+++ b/src/google/protobuf/message_lite.cc
@@ -195,14 +195,6 @@
 
 }  // namespace internal
 
-MessageLite* MessageLite::New(Arena* arena) const {
-  MessageLite* message = New();
-  if (arena != nullptr) {
-    arena->Own(message);
-  }
-  return message;
-}
-
 class ZeroCopyCodedInputStream : public io::ZeroCopyInputStream {
  public:
   ZeroCopyCodedInputStream(io::CodedInputStream* cis) : cis_(cis) {}
diff --git a/src/google/protobuf/message_lite.h b/src/google/protobuf/message_lite.h
index b41ee02..81cb8f8 100644
--- a/src/google/protobuf/message_lite.h
+++ b/src/google/protobuf/message_lite.h
@@ -46,13 +46,16 @@
 #include <google/protobuf/stubs/logging.h>
 #include <google/protobuf/io/coded_stream.h>
 #include <google/protobuf/arena.h>
+#include <google/protobuf/explicitly_constructed.h>
 #include <google/protobuf/metadata_lite.h>
 #include <google/protobuf/stubs/once.h>
 #include <google/protobuf/port.h>
 #include <google/protobuf/stubs/strutil.h>
 
 
+// clang-format off
 #include <google/protobuf/port_def.inc>
+// clang-format on
 
 #ifdef SWIG
 #error "You cannot SWIG proto headers"
@@ -126,43 +129,6 @@
   return static_cast<int>(size);
 }
 
-// This type wraps a variable whose constructor and destructor are explicitly
-// called. It is particularly useful for a global variable, without its
-// constructor and destructor run on start and end of the program lifetime.
-// This circumvents the initial construction order fiasco, while keeping
-// the address of the empty string a compile time constant.
-//
-// Pay special attention to the initialization state of the object.
-// 1. The object is "uninitialized" to begin with.
-// 2. Call Construct() or DefaultConstruct() only if the object is
-//    uninitialized. After the call, the object becomes "initialized".
-// 3. Call get() and get_mutable() only if the object is initialized.
-// 4. Call Destruct() only if the object is initialized.
-//    After the call, the object becomes uninitialized.
-template <typename T>
-class ExplicitlyConstructed {
- public:
-  void DefaultConstruct() { new (&union_) T(); }
-
-  template <typename... Args>
-  void Construct(Args&&... args) {
-    new (&union_) T(std::forward<Args>(args)...);
-  }
-
-  void Destruct() { get_mutable()->~T(); }
-
-  constexpr const T& get() const { return reinterpret_cast<const T&>(union_); }
-  T* get_mutable() { return reinterpret_cast<T*>(&union_); }
-
- private:
-  // Prefer c++14 aligned_storage, but for compatibility this will do.
-  union AlignedUnion {
-    alignas(T) char space[sizeof(T)];
-    int64_t align_to_int64;
-    void* align_to_ptr;
-  } union_;
-};
-
 // Default empty string object. Don't use this directly. Instead, call
 // GetEmptyString() to get the reference.
 PROTOBUF_EXPORT extern ExplicitlyConstructed<std::string>
@@ -215,28 +181,15 @@
 
   // Construct a new instance of the same type.  Ownership is passed to the
   // caller.
-  virtual MessageLite* New() const = 0;
+  MessageLite* New() const { return New(nullptr); }
 
   // Construct a new instance on the arena. Ownership is passed to the caller
-  // if arena is a nullptr. Default implementation for backwards compatibility.
-  virtual MessageLite* New(Arena* arena) const;
+  // if arena is a nullptr.
+  virtual MessageLite* New(Arena* arena) const = 0;
 
   // Same as GetOwningArena.
   Arena* GetArena() const { return GetOwningArena(); }
 
-  // Get a pointer that may be equal to this message's arena, or may not be.
-  // If the value returned by this method is equal to some arena pointer, then
-  // this message is on that arena; however, if this message is on some arena,
-  // this method may or may not return that arena's pointer. As a tradeoff,
-  // this method may be more efficient than GetArena(). The intent is to allow
-  // underlying representations that use e.g. tagged pointers to sometimes
-  // store the arena pointer directly, and sometimes in a more indirect way,
-  // and allow a fastpath comparison against the arena pointer when it's easy
-  // to obtain.
-  void* GetMaybeArenaPointer() const {
-    return _internal_metadata_.raw_arena_ptr();
-  }
-
   // Clear all fields of the message and set them to their default values.
   // Clear() avoids freeing memory, assuming that any memory allocated
   // to hold parts of the message will be needed again to hold the next
diff --git a/src/google/protobuf/message_unittest.cc b/src/google/protobuf/message_unittest.cc
index 0840e7b..f71f60c 100644
--- a/src/google/protobuf/message_unittest.cc
+++ b/src/google/protobuf/message_unittest.cc
@@ -41,5 +41,8 @@
 #define UNITTEST_IMPORT ::protobuf_unittest_import
 
 // Must include after the above macros.
+// clang-format off
 #include <google/protobuf/test_util.inc>
 #include <google/protobuf/message_unittest.inc>
+#include <google/protobuf/arena.h>
+// clang-format on
diff --git a/src/google/protobuf/parse_context.cc b/src/google/protobuf/parse_context.cc
index b515427..1aec2ae 100644
--- a/src/google/protobuf/parse_context.cc
+++ b/src/google/protobuf/parse_context.cc
@@ -460,7 +460,6 @@
 template <typename T>
 const char* FixedParser(void* object, const char* ptr, ParseContext* ctx) {
   int size = ReadSize(&ptr);
-  GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
   return ctx->ReadPackedFixed(ptr, size,
                               static_cast<RepeatedField<T>*>(object));
 }
diff --git a/src/google/protobuf/parse_context.h b/src/google/protobuf/parse_context.h
index 488b062..62e25dc 100644
--- a/src/google/protobuf/parse_context.h
+++ b/src/google/protobuf/parse_context.h
@@ -125,7 +125,7 @@
   }
 
   // If return value is negative it's an error
-  PROTOBUF_MUST_USE_RESULT int PushLimit(const char* ptr, int limit) {
+  PROTOBUF_NODISCARD int PushLimit(const char* ptr, int limit) {
     GOOGLE_DCHECK(limit >= 0 && limit <= INT_MAX - kSlopBytes);
     // This add is safe due to the invariant above, because
     // ptr - buffer_end_ <= kSlopBytes.
@@ -136,7 +136,7 @@
     return old_limit - limit;
   }
 
-  PROTOBUF_MUST_USE_RESULT bool PopLimit(int delta) {
+  PROTOBUF_NODISCARD bool PopLimit(int delta) {
     if (PROTOBUF_PREDICT_FALSE(!EndedAtLimit())) return false;
     limit_ = limit_ + delta;
     // TODO(gerbens) We could remove this line and hoist the code to
@@ -145,22 +145,22 @@
     return true;
   }
 
-  PROTOBUF_MUST_USE_RESULT const char* Skip(const char* ptr, int size) {
+  PROTOBUF_NODISCARD const char* Skip(const char* ptr, int size) {
     if (size <= buffer_end_ + kSlopBytes - ptr) {
       return ptr + size;
     }
     return SkipFallback(ptr, size);
   }
-  PROTOBUF_MUST_USE_RESULT const char* ReadString(const char* ptr, int size,
-                                                  std::string* s) {
+  PROTOBUF_NODISCARD const char* ReadString(const char* ptr, int size,
+                                            std::string* s) {
     if (size <= buffer_end_ + kSlopBytes - ptr) {
       s->assign(ptr, size);
       return ptr + size;
     }
     return ReadStringFallback(ptr, size, s);
   }
-  PROTOBUF_MUST_USE_RESULT const char* AppendString(const char* ptr, int size,
-                                                    std::string* s) {
+  PROTOBUF_NODISCARD const char* AppendString(const char* ptr, int size,
+                                              std::string* s) {
     if (size <= buffer_end_ + kSlopBytes - ptr) {
       s->append(ptr, size);
       return ptr + size;
@@ -168,22 +168,20 @@
     return AppendStringFallback(ptr, size, s);
   }
   // Implemented in arenastring.cc
-  PROTOBUF_MUST_USE_RESULT const char* ReadArenaString(const char* ptr,
-                                                       ArenaStringPtr* s,
-                                                       Arena* arena);
+  PROTOBUF_NODISCARD const char* ReadArenaString(const char* ptr,
+                                                 ArenaStringPtr* s,
+                                                 Arena* arena);
 
   template <typename Tag, typename T>
-  PROTOBUF_MUST_USE_RESULT const char* ReadRepeatedFixed(const char* ptr,
-                                                         Tag expected_tag,
-                                                         RepeatedField<T>* out);
+  PROTOBUF_NODISCARD const char* ReadRepeatedFixed(const char* ptr,
+                                                   Tag expected_tag,
+                                                   RepeatedField<T>* out);
 
   template <typename T>
-  PROTOBUF_MUST_USE_RESULT const char* ReadPackedFixed(const char* ptr,
-                                                       int size,
-                                                       RepeatedField<T>* out);
+  PROTOBUF_NODISCARD const char* ReadPackedFixed(const char* ptr, int size,
+                                                 RepeatedField<T>* out);
   template <typename Add>
-  PROTOBUF_MUST_USE_RESULT const char* ReadPackedVarint(const char* ptr,
-                                                        Add add);
+  PROTOBUF_NODISCARD const char* ReadPackedVarint(const char* ptr, Add add);
 
   uint32_t LastTag() const { return last_tag_minus_1_ + 1; }
   bool ConsumeEndGroup(uint32_t start_tag) {
@@ -364,8 +362,8 @@
     return end;
   }
 
-  PROTOBUF_MUST_USE_RESULT const char* AppendString(const char* ptr,
-                                                    std::string* str) {
+  PROTOBUF_NODISCARD const char* AppendString(const char* ptr,
+                                              std::string* str) {
     return AppendUntilEnd(
         ptr, [str](const char* p, ptrdiff_t s) { str->append(p, s); });
   }
@@ -407,10 +405,10 @@
   template <typename T,
             typename std::enable_if<!std::is_base_of<MessageLite, T>::value,
                                     bool>::type = true>
-  PROTOBUF_MUST_USE_RESULT const char* ParseMessage(T* msg, const char* ptr);
+  PROTOBUF_NODISCARD const char* ParseMessage(T* msg, const char* ptr);
 
   template <typename T>
-  PROTOBUF_MUST_USE_RESULT PROTOBUF_NDEBUG_INLINE const char* ParseGroup(
+  PROTOBUF_NODISCARD PROTOBUF_NDEBUG_INLINE const char* ParseGroup(
       T* msg, const char* ptr, uint32_t tag) {
     if (--depth_ < 0) return nullptr;
     group_depth_++;
@@ -430,8 +428,8 @@
   //   if (!ptr) return nullptr;
   //   int old = PushLimit(ptr, size);
   //   if (--depth_ < 0) return nullptr;
-  PROTOBUF_MUST_USE_RESULT const char* ReadSizeAndPushLimitAndDepth(
-      const char* ptr, int* old_limit);
+  PROTOBUF_NODISCARD const char* ReadSizeAndPushLimitAndDepth(const char* ptr,
+                                                              int* old_limit);
 
   // The context keeps an internal stack to keep track of the recursive
   // part of the parse state.
@@ -526,7 +524,7 @@
 }
 
 template <typename T>
-PROTOBUF_MUST_USE_RESULT const char* VarintParse(const char* p, T* out) {
+PROTOBUF_NODISCARD const char* VarintParse(const char* p, T* out) {
   auto ptr = reinterpret_cast<const uint8_t*>(p);
   uint32_t res = ptr[0];
   if (!(res & 0x80)) {
@@ -660,8 +658,8 @@
 
 template <typename T, typename std::enable_if<
                           !std::is_base_of<MessageLite, T>::value, bool>::type>
-PROTOBUF_MUST_USE_RESULT const char* ParseContext::ParseMessage(
-    T* msg, const char* ptr) {
+PROTOBUF_NODISCARD const char* ParseContext::ParseMessage(T* msg,
+                                                          const char* ptr) {
   int old;
   ptr = ReadSizeAndPushLimitAndDepth(ptr, &old);
   ptr = ptr ? msg->_InternalParse(ptr, this) : nullptr;
@@ -682,9 +680,22 @@
   return ptr;
 }
 
+// Add any of the following lines to debug which parse function is failing.
+
+#define GOOGLE_PROTOBUF_ASSERT_RETURN(predicate, ret) \
+  if (!(predicate)) {                                  \
+    /*  ::raise(SIGINT);  */                           \
+    /*  GOOGLE_LOG(ERROR) << "Parse failure";  */             \
+    return ret;                                        \
+  }
+
+#define GOOGLE_PROTOBUF_PARSER_ASSERT(predicate) \
+  GOOGLE_PROTOBUF_ASSERT_RETURN(predicate, nullptr)
+
 template <typename T>
 const char* EpsCopyInputStream::ReadPackedFixed(const char* ptr, int size,
                                                 RepeatedField<T>* out) {
+  GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
   int nbytes = buffer_end_ + kSlopBytes - ptr;
   while (size > nbytes) {
     int num = nbytes / sizeof(T);
@@ -734,7 +745,7 @@
 template <typename Add>
 const char* EpsCopyInputStream::ReadPackedVarint(const char* ptr, Add add) {
   int size = ReadSize(&ptr);
-  if (ptr == nullptr) return nullptr;
+  GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
   int chunk_size = buffer_end_ - ptr;
   while (size > chunk_size) {
     ptr = ReadPackedVarintArray(ptr, buffer_end_, add);
@@ -776,26 +787,13 @@
 }
 
 // All the string parsers with or without UTF checking and for all CTypes.
-PROTOBUF_EXPORT PROTOBUF_MUST_USE_RESULT const char* InlineGreedyStringParser(
+PROTOBUF_EXPORT PROTOBUF_NODISCARD const char* InlineGreedyStringParser(
     std::string* s, const char* ptr, ParseContext* ctx);
 
 
-// Add any of the following lines to debug which parse function is failing.
-
-#define GOOGLE_PROTOBUF_ASSERT_RETURN(predicate, ret) \
-  if (!(predicate)) {                                  \
-    /*  ::raise(SIGINT);  */                           \
-    /*  GOOGLE_LOG(ERROR) << "Parse failure";  */             \
-    return ret;                                        \
-  }
-
-#define GOOGLE_PROTOBUF_PARSER_ASSERT(predicate) \
-  GOOGLE_PROTOBUF_ASSERT_RETURN(predicate, nullptr)
-
 template <typename T>
-PROTOBUF_MUST_USE_RESULT const char* FieldParser(uint64_t tag, T& field_parser,
-                                                 const char* ptr,
-                                                 ParseContext* ctx) {
+PROTOBUF_NODISCARD const char* FieldParser(uint64_t tag, T& field_parser,
+                                           const char* ptr, ParseContext* ctx) {
   uint32_t number = tag >> 3;
   GOOGLE_PROTOBUF_PARSER_ASSERT(number != 0);
   using WireType = internal::WireFormatLite::WireType;
@@ -840,9 +838,9 @@
 }
 
 template <typename T>
-PROTOBUF_MUST_USE_RESULT const char* WireFormatParser(T& field_parser,
-                                                      const char* ptr,
-                                                      ParseContext* ctx) {
+PROTOBUF_NODISCARD const char* WireFormatParser(T& field_parser,
+                                                const char* ptr,
+                                                ParseContext* ctx) {
   while (!ctx->Done(&ptr)) {
     uint32_t tag;
     ptr = ReadTag(ptr, &tag);
@@ -861,25 +859,27 @@
 // corresponding field
 
 // These are packed varints
-PROTOBUF_EXPORT PROTOBUF_MUST_USE_RESULT const char* PackedInt32Parser(
+PROTOBUF_EXPORT PROTOBUF_NODISCARD const char* PackedInt32Parser(
     void* object, const char* ptr, ParseContext* ctx);
-PROTOBUF_EXPORT PROTOBUF_MUST_USE_RESULT const char* PackedUInt32Parser(
+PROTOBUF_EXPORT PROTOBUF_NODISCARD const char* PackedUInt32Parser(
     void* object, const char* ptr, ParseContext* ctx);
-PROTOBUF_EXPORT PROTOBUF_MUST_USE_RESULT const char* PackedInt64Parser(
+PROTOBUF_EXPORT PROTOBUF_NODISCARD const char* PackedInt64Parser(
     void* object, const char* ptr, ParseContext* ctx);
-PROTOBUF_EXPORT PROTOBUF_MUST_USE_RESULT const char* PackedUInt64Parser(
+PROTOBUF_EXPORT PROTOBUF_NODISCARD const char* PackedUInt64Parser(
     void* object, const char* ptr, ParseContext* ctx);
-PROTOBUF_EXPORT PROTOBUF_MUST_USE_RESULT const char* PackedSInt32Parser(
+PROTOBUF_EXPORT PROTOBUF_NODISCARD const char* PackedSInt32Parser(
     void* object, const char* ptr, ParseContext* ctx);
-PROTOBUF_EXPORT PROTOBUF_MUST_USE_RESULT const char* PackedSInt64Parser(
+PROTOBUF_EXPORT PROTOBUF_NODISCARD const char* PackedSInt64Parser(
     void* object, const char* ptr, ParseContext* ctx);
-PROTOBUF_EXPORT PROTOBUF_MUST_USE_RESULT const char* PackedEnumParser(
+PROTOBUF_EXPORT PROTOBUF_NODISCARD const char* PackedEnumParser(
     void* object, const char* ptr, ParseContext* ctx);
 
 template <typename T>
-PROTOBUF_MUST_USE_RESULT const char* PackedEnumParser(
-    void* object, const char* ptr, ParseContext* ctx, bool (*is_valid)(int),
-    InternalMetadata* metadata, int field_num) {
+PROTOBUF_NODISCARD const char* PackedEnumParser(void* object, const char* ptr,
+                                                ParseContext* ctx,
+                                                bool (*is_valid)(int),
+                                                InternalMetadata* metadata,
+                                                int field_num) {
   return ctx->ReadPackedVarint(
       ptr, [object, is_valid, metadata, field_num](uint64_t val) {
         if (is_valid(val)) {
@@ -891,7 +891,7 @@
 }
 
 template <typename T>
-PROTOBUF_MUST_USE_RESULT const char* PackedEnumParserArg(
+PROTOBUF_NODISCARD const char* PackedEnumParserArg(
     void* object, const char* ptr, ParseContext* ctx,
     bool (*is_valid)(const void*, int), const void* data,
     InternalMetadata* metadata, int field_num) {
@@ -905,28 +905,28 @@
       });
 }
 
-PROTOBUF_EXPORT PROTOBUF_MUST_USE_RESULT const char* PackedBoolParser(
+PROTOBUF_EXPORT PROTOBUF_NODISCARD const char* PackedBoolParser(
     void* object, const char* ptr, ParseContext* ctx);
-PROTOBUF_EXPORT PROTOBUF_MUST_USE_RESULT const char* PackedFixed32Parser(
+PROTOBUF_EXPORT PROTOBUF_NODISCARD const char* PackedFixed32Parser(
     void* object, const char* ptr, ParseContext* ctx);
-PROTOBUF_EXPORT PROTOBUF_MUST_USE_RESULT const char* PackedSFixed32Parser(
+PROTOBUF_EXPORT PROTOBUF_NODISCARD const char* PackedSFixed32Parser(
     void* object, const char* ptr, ParseContext* ctx);
-PROTOBUF_EXPORT PROTOBUF_MUST_USE_RESULT const char* PackedFixed64Parser(
+PROTOBUF_EXPORT PROTOBUF_NODISCARD const char* PackedFixed64Parser(
     void* object, const char* ptr, ParseContext* ctx);
-PROTOBUF_EXPORT PROTOBUF_MUST_USE_RESULT const char* PackedSFixed64Parser(
+PROTOBUF_EXPORT PROTOBUF_NODISCARD const char* PackedSFixed64Parser(
     void* object, const char* ptr, ParseContext* ctx);
-PROTOBUF_EXPORT PROTOBUF_MUST_USE_RESULT const char* PackedFloatParser(
+PROTOBUF_EXPORT PROTOBUF_NODISCARD const char* PackedFloatParser(
     void* object, const char* ptr, ParseContext* ctx);
-PROTOBUF_EXPORT PROTOBUF_MUST_USE_RESULT const char* PackedDoubleParser(
+PROTOBUF_EXPORT PROTOBUF_NODISCARD const char* PackedDoubleParser(
     void* object, const char* ptr, ParseContext* ctx);
 
 // This is the only recursive parser.
-PROTOBUF_EXPORT PROTOBUF_MUST_USE_RESULT const char* UnknownGroupLiteParse(
+PROTOBUF_EXPORT PROTOBUF_NODISCARD const char* UnknownGroupLiteParse(
     std::string* unknown, const char* ptr, ParseContext* ctx);
 // This is a helper to for the UnknownGroupLiteParse but is actually also
 // useful in the generated code. It uses overload on std::string* vs
 // UnknownFieldSet* to make the generated code isomorphic between full and lite.
-PROTOBUF_EXPORT PROTOBUF_MUST_USE_RESULT const char* UnknownFieldParse(
+PROTOBUF_EXPORT PROTOBUF_NODISCARD const char* UnknownFieldParse(
     uint32_t tag, std::string* unknown, const char* ptr, ParseContext* ctx);
 
 }  // namespace internal
diff --git a/src/google/protobuf/port_def.inc b/src/google/protobuf/port_def.inc
index 4f73ff9..aff8c8f 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 3017003
+#define PROTOBUF_VERSION 3018000
 
 #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 3017000
+#define PROTOBUF_MIN_HEADER_VERSION_FOR_PROTOC 3018000
 
 #ifdef PROTOBUF_MIN_PROTOC_VERSION
 #error PROTOBUF_MIN_PROTOC_VERSION was previously defined
 #endif
-#define PROTOBUF_MIN_PROTOC_VERSION 3017000
+#define PROTOBUF_MIN_PROTOC_VERSION 3018000
 
 #ifdef PROTOBUF_VERSION_SUFFIX
 #error PROTOBUF_VERSION_SUFFIX was previously defined
@@ -293,7 +293,12 @@
 #ifdef PROTOBUF_SECTION_VARIABLE
 #error PROTOBUF_SECTION_VARIABLE was previously defined
 #endif
-#define PROTOBUF_SECTION_VARIABLE(x)
+#if (__has_attribute(section) || defined(__GNUC__)) && defined(__ELF__)
+// Place a variable in the given ELF section.
+# define PROTOBUF_SECTION_VARIABLE(x) __attribute__((section(#x)))
+#else
+# define PROTOBUF_SECTION_VARIABLE(x)
+#endif
 
 #if defined(PROTOBUF_DEPRECATED)
 #error PROTOBUF_DEPRECATED was previously defined
@@ -351,7 +356,7 @@
 
 // The minimum library version which works with the current version of the
 // headers.
-#define GOOGLE_PROTOBUF_MIN_LIBRARY_VERSION 3017000
+#define GOOGLE_PROTOBUF_MIN_LIBRARY_VERSION 3018000
 
 #ifdef PROTOBUF_RTTI
 #error PROTOBUF_RTTI was previously defined
@@ -451,10 +456,16 @@
 # define PROTOBUF_PREDICT_FALSE(x) (x)
 #endif
 
-#ifdef PROTOBUF_MUST_USE_RESULT
-#error PROTOBUF_MUST_USE_RESULT was previously defined
+#ifdef PROTOBUF_NODISCARD
+#error PROTOBUF_NODISCARD was previously defined
 #endif
-# define PROTOBUF_MUST_USE_RESULT
+#if __has_cpp_attribute(nodiscard)
+#define PROTOBUF_NODISCARD [[nodiscard]]
+#elif __has_attribute(warn_unused_result) || PROTOBUF_GNUC_MIN(4, 8)
+#define PROTOBUF_NODISCARD __attribute__((warn_unused_result))
+#else
+#define PROTOBUF_NODISCARD
+#endif
 
 #ifdef PROTOBUF_FORCE_COPY_IN_RELEASE
 #error PROTOBUF_FORCE_COPY_IN_RELEASE was previously defined
@@ -568,7 +579,7 @@
 // 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)
+#elif !defined(_MSC_VER) && __has_cpp_attribute(clang::require_constant_initialization)
 #define PROTOBUF_CONSTINIT [[clang::require_constant_initialization]]
 #else
 #define PROTOBUF_CONSTINIT
@@ -646,8 +657,17 @@
 #    define PROTOBUF_MSAN 1
 #  endif
 #elif PROTOBUF_GNUC_MIN(3, 0)
-#  define PROTOBUF_ASAN __SANITIZE_ADDRESS__
-#  define PROTOBUF_TSAN __SANITIZE_THREAD__
+// Double-guard is needed for -Wundef:
+#  ifdef __SANITIZE_ADDRESS__
+#  if    __SANITIZE_ADDRESS__
+#    define PROTOBUF_ASAN 1
+#  endif
+#  endif
+#  ifdef __SANITIZE_THREAD__
+#  if    __SANITIZE_THREAD__
+#    define PROTOBUF_TSAN 1
+#  endif
+#  endif
 #endif
 
 // Tail call table-driven parsing can be enabled by defining
diff --git a/src/google/protobuf/port_undef.inc b/src/google/protobuf/port_undef.inc
index ad57f86..579eb41 100644
--- a/src/google/protobuf/port_undef.inc
+++ b/src/google/protobuf/port_undef.inc
@@ -63,7 +63,7 @@
 #undef PROTOBUF_FALLTHROUGH_INTENDED
 #undef PROTOBUF_EXPORT
 #undef PROTOC_EXPORT
-#undef PROTOBUF_MUST_USE_RESULT
+#undef PROTOBUF_NODISCARD
 #undef PROTOBUF_FORCE_COPY_IN_RELEASE
 #undef PROTOBUF_FORCE_COPY_IN_SWAP
 #undef PROTOBUF_FORCE_COPY_IN_MOVE
diff --git a/src/google/protobuf/repeated_field.h b/src/google/protobuf/repeated_field.h
index 44dd10c..b52e016 100644
--- a/src/google/protobuf/repeated_field.h
+++ b/src/google/protobuf/repeated_field.h
@@ -698,7 +698,7 @@
   void UnsafeArenaAddAllocated(typename TypeHandler::Type* value);
 
   template <typename TypeHandler>
-  PROTOBUF_MUST_USE_RESULT typename TypeHandler::Type* ReleaseLast() {
+  PROTOBUF_NODISCARD typename TypeHandler::Type* ReleaseLast() {
     typename TypeImplementsMergeBehavior<typename TypeHandler::Type>::type t;
     return ReleaseLastInternal<TypeHandler>(t);
   }
@@ -712,7 +712,7 @@
   template <typename TypeHandler>
   void AddCleared(typename TypeHandler::Type* value);
   template <typename TypeHandler>
-  PROTOBUF_MUST_USE_RESULT typename TypeHandler::Type* ReleaseCleared();
+  PROTOBUF_NODISCARD typename TypeHandler::Type* ReleaseCleared();
 
   template <typename TypeHandler>
   void AddAllocatedInternal(typename TypeHandler::Type* value, std::true_type);
@@ -1084,7 +1084,7 @@
   // If this RepeatedPtrField is on an arena, an object copy is required to pass
   // ownership back to the user (for compatible semantics). Use
   // UnsafeArenaReleaseLast() if this behavior is undesired.
-  PROTOBUF_MUST_USE_RESULT Element* ReleaseLast();
+  PROTOBUF_NODISCARD Element* ReleaseLast();
 
   // Add an already-allocated object, skipping arena-ownership checks. The user
   // must guarantee that the given object is in the same arena as this
@@ -1155,7 +1155,7 @@
   //
   // This method cannot be called when the repeated field is on an arena; doing
   // so will trigger a GOOGLE_DCHECK-failure.
-  PROTOBUF_MUST_USE_RESULT Element* ReleaseCleared();
+  PROTOBUF_NODISCARD Element* ReleaseCleared();
 #endif  // !PROTOBUF_FUTURE_BREAKING_CHANGES
 
   // Removes the element referenced by position.
diff --git a/src/google/protobuf/source_context.pb.h b/src/google/protobuf/source_context.pb.h
index 64377a6..0543017 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 < 3017000
+#if PROTOBUF_VERSION < 3018000
 #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 3017003 < PROTOBUF_MIN_PROTOC_VERSION
+#if 3018000 < 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.
@@ -139,11 +139,7 @@
 
   // implements Message ----------------------------------------------
 
-  inline SourceContext* New() const final {
-    return new SourceContext();
-  }
-
-  SourceContext* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final {
+  SourceContext* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final {
     return CreateMaybeMessage<SourceContext>(arena);
   }
   using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom;
@@ -167,6 +163,8 @@
   void SharedDtor();
   void SetCachedSize(int size) const final;
   void InternalSwap(SourceContext* other);
+
+  private:
   friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
   static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
     return "google.protobuf.SourceContext";
@@ -197,7 +195,7 @@
   template <typename ArgT0 = const std::string&, typename... ArgT>
   void set_file_name(ArgT0&& arg0, ArgT... args);
   std::string* mutable_file_name();
-  PROTOBUF_MUST_USE_RESULT std::string* release_file_name();
+  PROTOBUF_NODISCARD std::string* release_file_name();
   void set_allocated_file_name(std::string* file_name);
   private:
   const std::string& _internal_file_name() const;
diff --git a/src/google/protobuf/struct.pb.h b/src/google/protobuf/struct.pb.h
index 716e66c..165a9d9 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 < 3017000
+#if PROTOBUF_VERSION < 3018000
 #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 3017003 < PROTOBUF_MIN_PROTOC_VERSION
+#if 3018000 < 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.
@@ -204,11 +204,7 @@
 
   // implements Message ----------------------------------------------
 
-  inline Struct* New() const final {
-    return new Struct();
-  }
-
-  Struct* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final {
+  Struct* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final {
     return CreateMaybeMessage<Struct>(arena);
   }
   using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom;
@@ -232,6 +228,8 @@
   void SharedDtor();
   void SetCachedSize(int size) const final;
   void InternalSwap(Struct* other);
+
+  private:
   friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
   static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
     return "google.protobuf.Struct";
@@ -375,11 +373,7 @@
 
   // implements Message ----------------------------------------------
 
-  inline Value* New() const final {
-    return new Value();
-  }
-
-  Value* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final {
+  Value* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final {
     return CreateMaybeMessage<Value>(arena);
   }
   using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom;
@@ -403,6 +397,8 @@
   void SharedDtor();
   void SetCachedSize(int size) const final;
   void InternalSwap(Value* other);
+
+  private:
   friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
   static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
     return "google.protobuf.Value";
@@ -468,7 +464,7 @@
   template <typename ArgT0 = const std::string&, typename... ArgT>
   void set_string_value(ArgT0&& arg0, ArgT... args);
   std::string* mutable_string_value();
-  PROTOBUF_MUST_USE_RESULT std::string* release_string_value();
+  PROTOBUF_NODISCARD std::string* release_string_value();
   void set_allocated_string_value(std::string* string_value);
   private:
   const std::string& _internal_string_value() const;
@@ -496,7 +492,7 @@
   public:
   void clear_struct_value();
   const ::PROTOBUF_NAMESPACE_ID::Struct& struct_value() const;
-  PROTOBUF_MUST_USE_RESULT ::PROTOBUF_NAMESPACE_ID::Struct* release_struct_value();
+  PROTOBUF_NODISCARD ::PROTOBUF_NAMESPACE_ID::Struct* release_struct_value();
   ::PROTOBUF_NAMESPACE_ID::Struct* mutable_struct_value();
   void set_allocated_struct_value(::PROTOBUF_NAMESPACE_ID::Struct* struct_value);
   private:
@@ -514,7 +510,7 @@
   public:
   void clear_list_value();
   const ::PROTOBUF_NAMESPACE_ID::ListValue& list_value() const;
-  PROTOBUF_MUST_USE_RESULT ::PROTOBUF_NAMESPACE_ID::ListValue* release_list_value();
+  PROTOBUF_NODISCARD ::PROTOBUF_NAMESPACE_ID::ListValue* release_list_value();
   ::PROTOBUF_NAMESPACE_ID::ListValue* mutable_list_value();
   void set_allocated_list_value(::PROTOBUF_NAMESPACE_ID::ListValue* list_value);
   private:
@@ -634,11 +630,7 @@
 
   // implements Message ----------------------------------------------
 
-  inline ListValue* New() const final {
-    return new ListValue();
-  }
-
-  ListValue* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final {
+  ListValue* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final {
     return CreateMaybeMessage<ListValue>(arena);
   }
   using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom;
@@ -662,6 +654,8 @@
   void SharedDtor();
   void SetCachedSize(int size) const final;
   void InternalSwap(ListValue* other);
+
+  private:
   friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
   static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
     return "google.protobuf.ListValue";
diff --git a/src/google/protobuf/stubs/common.h b/src/google/protobuf/stubs/common.h
index 821e1cc..3e74713 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 3017003
+#define GOOGLE_PROTOBUF_VERSION 3018000
 
 // 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 = 3017000;
+static const int kMinHeaderVersionForLibrary = 3018000;
 
 // The minimum protoc version which works with the current version of the
 // headers.
-#define GOOGLE_PROTOBUF_MIN_PROTOC_VERSION 3017000
+#define GOOGLE_PROTOBUF_MIN_PROTOC_VERSION 3018000
 
 // The minimum header version which works with the current version of
 // protoc.  This constant should only be used in VerifyVersion().
-static const int kMinHeaderVersionForProtoc = 3017000;
+static const int kMinHeaderVersionForProtoc = 3018000;
 
 // Verifies that the headers and libraries are compatible.  Use the macro
 // below to call this.
diff --git a/src/google/protobuf/stubs/strutil.cc b/src/google/protobuf/stubs/strutil.cc
index 6d62d7c..6bead9a 100644
--- a/src/google/protobuf/stubs/strutil.cc
+++ b/src/google/protobuf/stubs/strutil.cc
@@ -1273,7 +1273,7 @@
   volatile double parsed_value = internal::NoLocaleStrtod(buffer, nullptr);
   if (parsed_value != value) {
     snprintf_result =
-      snprintf(buffer, kDoubleToBufferSize, "%.*g", DBL_DIG+2, value);
+        snprintf(buffer, kDoubleToBufferSize, "%.*g", DBL_DIG + 2, value);
 
     // Should never overflow; see above.
     GOOGLE_DCHECK(snprintf_result > 0 && snprintf_result < kDoubleToBufferSize);
@@ -1385,7 +1385,7 @@
   float parsed_value;
   if (!safe_strtof(buffer, &parsed_value) || parsed_value != value) {
     snprintf_result =
-      snprintf(buffer, kFloatToBufferSize, "%.*g", FLT_DIG+3, value);
+        snprintf(buffer, kFloatToBufferSize, "%.*g", FLT_DIG + 3, value);
 
     // Should never overflow; see above.
     GOOGLE_DCHECK(snprintf_result > 0 && snprintf_result < kFloatToBufferSize);
diff --git a/src/google/protobuf/text_format.cc b/src/google/protobuf/text_format.cc
index 4207c4a..c94fb7e 100644
--- a/src/google/protobuf/text_format.cc
+++ b/src/google/protobuf/text_format.cc
@@ -38,6 +38,7 @@
 #include <stdio.h>
 
 #include <algorithm>
+#include <atomic>
 #include <climits>
 #include <cmath>
 #include <limits>
@@ -84,11 +85,18 @@
 
 }  // namespace
 
+namespace internal {
+// Controls insertion of DEBUG_STRING_SILENT_MARKER.
+PROTOBUF_EXPORT std::atomic<bool> enable_debug_text_format_marker;
+}  // namespace internal
+
 std::string Message::DebugString() const {
   std::string debug_string;
 
   TextFormat::Printer printer;
   printer.SetExpandAny(true);
+  printer.SetInsertSilentMarker(internal::enable_debug_text_format_marker.load(
+      std::memory_order_relaxed));
 
   printer.PrintToString(*this, &debug_string);
 
@@ -101,6 +109,8 @@
   TextFormat::Printer printer;
   printer.SetSingleLineMode(true);
   printer.SetExpandAny(true);
+  printer.SetInsertSilentMarker(internal::enable_debug_text_format_marker.load(
+      std::memory_order_relaxed));
 
   printer.PrintToString(*this, &debug_string);
   // Single line mode currently might have an extra space at the end.
@@ -117,6 +127,8 @@
   TextFormat::Printer printer;
   printer.SetUseUtf8StringEscaping(true);
   printer.SetExpandAny(true);
+  printer.SetInsertSilentMarker(internal::enable_debug_text_format_marker.load(
+      std::memory_order_relaxed));
 
   printer.PrintToString(*this, &debug_string);
 
@@ -1554,7 +1566,6 @@
   return Parse(&input_stream, output);
 }
 
-
 bool TextFormat::Parser::Merge(io::ZeroCopyInputStream* input,
                                Message* output) {
   ParserImpl parser(output->GetDescriptor(), input, error_collector_, finder_,
diff --git a/src/google/protobuf/text_format.h b/src/google/protobuf/text_format.h
index 3239663..f2c8dc3 100644
--- a/src/google/protobuf/text_format.h
+++ b/src/google/protobuf/text_format.h
@@ -365,6 +365,13 @@
                                 const MessagePrinter* printer);
 
    private:
+    friend std::string Message::DebugString() const;
+    friend std::string Message::ShortDebugString() const;
+    friend std::string Message::Utf8DebugString() const;
+
+    // Sets whether *DebugString should insert a silent marker.
+    void SetInsertSilentMarker(bool v) { insert_silent_marker_ = v; }
+
     // Forward declaration of an internal class used to print the text
     // output to the OutputStream (see text_format.cc for implementation).
     class TextGenerator;
diff --git a/src/google/protobuf/text_format_unittest.cc b/src/google/protobuf/text_format_unittest.cc
index 3c44be0..bc998b2 100644
--- a/src/google/protobuf/text_format_unittest.cc
+++ b/src/google/protobuf/text_format_unittest.cc
@@ -37,6 +37,7 @@
 #include <math.h>
 #include <stdlib.h>
 
+#include <atomic>
 #include <limits>
 #include <memory>
 
@@ -44,6 +45,7 @@
 #include <google/protobuf/stubs/common.h>
 #include <google/protobuf/testing/file.h>
 #include <google/protobuf/testing/file.h>
+#include <google/protobuf/any.pb.h>
 #include <google/protobuf/map_unittest.pb.h>
 #include <google/protobuf/test_util.h>
 #include <google/protobuf/test_util2.h>
@@ -66,6 +68,11 @@
 namespace google {
 namespace protobuf {
 
+namespace internal {
+// Controls insertion of DEBUG_STRING_SILENT_MARKER.
+extern PROTOBUF_EXPORT std::atomic<bool> enable_debug_text_format_marker;
+}  // namespace internal
+
 // Can't use an anonymous namespace here due to brokenness of Tru64 compiler.
 namespace text_format_unittest {
 
@@ -2147,6 +2154,130 @@
   EXPECT_FALSE(parser.ParseFromString("unknown_field: 1", &proto));
 }
 
+class TextFormatSilentMarkerTest : public testing::Test {
+ public:
+  void SetUp() override {
+    google::protobuf::internal::enable_debug_text_format_marker = true;
+  }
+  void TearDown() override {
+    google::protobuf::internal::enable_debug_text_format_marker = false;
+  }
+};
+
+TEST_F(TextFormatSilentMarkerTest, NonMessageFieldAsFirstField) {
+  protobuf_unittest::TestAllTypes proto;
+  proto.set_optional_int32(1);
+  proto.mutable_optional_nested_message()->set_bb(2);
+
+  EXPECT_EQ(
+      "optional_int32: \t 1\n"
+      "optional_nested_message {\n"
+      "  bb: 2\n"
+      "}\n",
+      proto.DebugString());
+
+  EXPECT_EQ(
+      "optional_int32: \t 1 "
+      "optional_nested_message { bb: 2 }",
+      proto.ShortDebugString());
+}
+
+TEST_F(TextFormatSilentMarkerTest, MessageFieldAsFirstField) {
+  protobuf_unittest::TestAllTypes proto;
+  proto.mutable_optional_nested_message()->set_bb(2);
+  proto.add_repeated_int32(3);
+
+  EXPECT_EQ(
+      "optional_nested_message \t {\n"
+      "  bb: 2\n"
+      "}\n"
+      "repeated_int32: 3\n",
+      proto.DebugString());
+
+  EXPECT_EQ(
+      "optional_nested_message \t { bb: 2 } "
+      "repeated_int32: 3",
+      proto.ShortDebugString());
+}
+
+TEST_F(TextFormatSilentMarkerTest, UnknownFieldAsFirstField) {
+  unittest::TestEmptyMessage message;
+  UnknownFieldSet* unknown_fields = message.mutable_unknown_fields();
+
+  unknown_fields->AddVarint(5, 1);
+  unknown_fields->AddGroup(5)->AddVarint(10, 5);
+
+  EXPECT_EQ(
+      "5: \t 1\n"
+      "5 {\n"
+      "  10: 5\n"
+      "}\n",
+      message.DebugString());
+
+  EXPECT_EQ(
+      "5: \t 1 "
+      "5 { 10: 5 }",
+      message.ShortDebugString());
+
+  unknown_fields->Clear();
+  unknown_fields->AddGroup(5)->AddVarint(10, 5);
+  unknown_fields->AddVarint(5, 1);
+
+  EXPECT_EQ(
+      "5 \t {\n"
+      "  10: 5\n"
+      "}\n"
+      "5: 1\n",
+      message.DebugString());
+
+  EXPECT_EQ(
+      "5 \t { 10: 5 } "
+      "5: 1",
+      message.ShortDebugString());
+}
+
+TEST_F(TextFormatSilentMarkerTest, AnyFieldAsFirstField) {
+  protobuf_unittest::TestAllTypes proto;
+  proto.set_optional_string("teststr");
+  proto.set_optional_int32(432);
+  Any any;
+  any.PackFrom(proto);
+
+  EXPECT_EQ(
+      "[type.googleapis.com/protobuf_unittest.TestAllTypes] \t {\n"
+      "  optional_int32: 432\n"
+      "  optional_string: \"teststr\"\n"
+      "}\n",
+      any.DebugString());
+
+  EXPECT_EQ(
+      "[type.googleapis.com/protobuf_unittest.TestAllTypes]"
+      " \t { optional_int32: 432 optional_string: \"teststr\" }",
+      any.ShortDebugString());
+}
+
+TEST_F(TextFormatSilentMarkerTest, ExtensionFieldAsFirstField) {
+  unittest::TestAllExtensions proto;
+  proto.SetExtension(protobuf_unittest::optional_int32_extension, 101);
+  proto.SetExtension(protobuf_unittest::optional_int64_extension, 102);
+
+  EXPECT_EQ(
+      "[protobuf_unittest.optional_int32_extension]: \t 101\n"
+      "[protobuf_unittest.optional_int64_extension]: 102\n",
+      proto.DebugString());
+}
+
+TEST_F(TextFormatSilentMarkerTest, MapFieldAsFirstField) {
+  unittest::TestMap proto;
+  (*proto.mutable_map_int32_int32())[0] = 1;
+  (*proto.mutable_map_int64_int64())[2] = 3;
+
+  EXPECT_EQ(
+      "map_int32_int32 \t {\n  key: 0\n  value: 1\n}\n"
+      "map_int64_int64 {\n  key: 2\n  value: 3\n}\n",
+      proto.DebugString());
+}
+
 
 }  // namespace text_format_unittest
 }  // namespace protobuf
diff --git a/src/google/protobuf/timestamp.pb.h b/src/google/protobuf/timestamp.pb.h
index aebf4ca..e4f6b2e 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 < 3017000
+#if PROTOBUF_VERSION < 3018000
 #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 3017003 < PROTOBUF_MIN_PROTOC_VERSION
+#if 3018000 < 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.
@@ -139,11 +139,7 @@
 
   // implements Message ----------------------------------------------
 
-  inline Timestamp* New() const final {
-    return new Timestamp();
-  }
-
-  Timestamp* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final {
+  Timestamp* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final {
     return CreateMaybeMessage<Timestamp>(arena);
   }
   using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom;
@@ -167,6 +163,8 @@
   void SharedDtor();
   void SetCachedSize(int size) const final;
   void InternalSwap(Timestamp* other);
+
+  private:
   friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
   static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
     return "google.protobuf.Timestamp";
diff --git a/src/google/protobuf/type.pb.h b/src/google/protobuf/type.pb.h
index 33bb4a6..97fe57b 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 < 3017000
+#if PROTOBUF_VERSION < 3018000
 #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 3017003 < PROTOBUF_MIN_PROTOC_VERSION
+#if 3018000 < 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.
@@ -252,11 +252,7 @@
 
   // implements Message ----------------------------------------------
 
-  inline Type* New() const final {
-    return new Type();
-  }
-
-  Type* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final {
+  Type* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final {
     return CreateMaybeMessage<Type>(arena);
   }
   using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom;
@@ -280,6 +276,8 @@
   void SharedDtor();
   void SetCachedSize(int size) const final;
   void InternalSwap(Type* other);
+
+  private:
   friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
   static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
     return "google.protobuf.Type";
@@ -375,7 +373,7 @@
   template <typename ArgT0 = const std::string&, typename... ArgT>
   void set_name(ArgT0&& arg0, ArgT... args);
   std::string* mutable_name();
-  PROTOBUF_MUST_USE_RESULT std::string* release_name();
+  PROTOBUF_NODISCARD std::string* release_name();
   void set_allocated_name(std::string* name);
   private:
   const std::string& _internal_name() const;
@@ -390,7 +388,7 @@
   public:
   void clear_source_context();
   const ::PROTOBUF_NAMESPACE_ID::SourceContext& source_context() const;
-  PROTOBUF_MUST_USE_RESULT ::PROTOBUF_NAMESPACE_ID::SourceContext* release_source_context();
+  PROTOBUF_NODISCARD ::PROTOBUF_NAMESPACE_ID::SourceContext* release_source_context();
   ::PROTOBUF_NAMESPACE_ID::SourceContext* mutable_source_context();
   void set_allocated_source_context(::PROTOBUF_NAMESPACE_ID::SourceContext* source_context);
   private:
@@ -502,11 +500,7 @@
 
   // implements Message ----------------------------------------------
 
-  inline Field* New() const final {
-    return new Field();
-  }
-
-  Field* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final {
+  Field* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final {
     return CreateMaybeMessage<Field>(arena);
   }
   using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom;
@@ -530,6 +524,8 @@
   void SharedDtor();
   void SetCachedSize(int size) const final;
   void InternalSwap(Field* other);
+
+  private:
   friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
   static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
     return "google.protobuf.Field";
@@ -685,7 +681,7 @@
   template <typename ArgT0 = const std::string&, typename... ArgT>
   void set_name(ArgT0&& arg0, ArgT... args);
   std::string* mutable_name();
-  PROTOBUF_MUST_USE_RESULT std::string* release_name();
+  PROTOBUF_NODISCARD std::string* release_name();
   void set_allocated_name(std::string* name);
   private:
   const std::string& _internal_name() const;
@@ -699,7 +695,7 @@
   template <typename ArgT0 = const std::string&, typename... ArgT>
   void set_type_url(ArgT0&& arg0, ArgT... args);
   std::string* mutable_type_url();
-  PROTOBUF_MUST_USE_RESULT std::string* release_type_url();
+  PROTOBUF_NODISCARD std::string* release_type_url();
   void set_allocated_type_url(std::string* type_url);
   private:
   const std::string& _internal_type_url() const;
@@ -713,7 +709,7 @@
   template <typename ArgT0 = const std::string&, typename... ArgT>
   void set_json_name(ArgT0&& arg0, ArgT... args);
   std::string* mutable_json_name();
-  PROTOBUF_MUST_USE_RESULT std::string* release_json_name();
+  PROTOBUF_NODISCARD std::string* release_json_name();
   void set_allocated_json_name(std::string* json_name);
   private:
   const std::string& _internal_json_name() const;
@@ -727,7 +723,7 @@
   template <typename ArgT0 = const std::string&, typename... ArgT>
   void set_default_value(ArgT0&& arg0, ArgT... args);
   std::string* mutable_default_value();
-  PROTOBUF_MUST_USE_RESULT std::string* release_default_value();
+  PROTOBUF_NODISCARD std::string* release_default_value();
   void set_allocated_default_value(std::string* default_value);
   private:
   const std::string& _internal_default_value() const;
@@ -876,11 +872,7 @@
 
   // implements Message ----------------------------------------------
 
-  inline Enum* New() const final {
-    return new Enum();
-  }
-
-  Enum* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final {
+  Enum* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final {
     return CreateMaybeMessage<Enum>(arena);
   }
   using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom;
@@ -904,6 +896,8 @@
   void SharedDtor();
   void SetCachedSize(int size) const final;
   void InternalSwap(Enum* other);
+
+  private:
   friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
   static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
     return "google.protobuf.Enum";
@@ -974,7 +968,7 @@
   template <typename ArgT0 = const std::string&, typename... ArgT>
   void set_name(ArgT0&& arg0, ArgT... args);
   std::string* mutable_name();
-  PROTOBUF_MUST_USE_RESULT std::string* release_name();
+  PROTOBUF_NODISCARD std::string* release_name();
   void set_allocated_name(std::string* name);
   private:
   const std::string& _internal_name() const;
@@ -989,7 +983,7 @@
   public:
   void clear_source_context();
   const ::PROTOBUF_NAMESPACE_ID::SourceContext& source_context() const;
-  PROTOBUF_MUST_USE_RESULT ::PROTOBUF_NAMESPACE_ID::SourceContext* release_source_context();
+  PROTOBUF_NODISCARD ::PROTOBUF_NAMESPACE_ID::SourceContext* release_source_context();
   ::PROTOBUF_NAMESPACE_ID::SourceContext* mutable_source_context();
   void set_allocated_source_context(::PROTOBUF_NAMESPACE_ID::SourceContext* source_context);
   private:
@@ -1100,11 +1094,7 @@
 
   // implements Message ----------------------------------------------
 
-  inline EnumValue* New() const final {
-    return new EnumValue();
-  }
-
-  EnumValue* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final {
+  EnumValue* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final {
     return CreateMaybeMessage<EnumValue>(arena);
   }
   using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom;
@@ -1128,6 +1118,8 @@
   void SharedDtor();
   void SetCachedSize(int size) const final;
   void InternalSwap(EnumValue* other);
+
+  private:
   friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
   static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
     return "google.protobuf.EnumValue";
@@ -1178,7 +1170,7 @@
   template <typename ArgT0 = const std::string&, typename... ArgT>
   void set_name(ArgT0&& arg0, ArgT... args);
   std::string* mutable_name();
-  PROTOBUF_MUST_USE_RESULT std::string* release_name();
+  PROTOBUF_NODISCARD std::string* release_name();
   void set_allocated_name(std::string* name);
   private:
   const std::string& _internal_name() const;
@@ -1284,11 +1276,7 @@
 
   // implements Message ----------------------------------------------
 
-  inline Option* New() const final {
-    return new Option();
-  }
-
-  Option* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final {
+  Option* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final {
     return CreateMaybeMessage<Option>(arena);
   }
   using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom;
@@ -1312,6 +1300,8 @@
   void SharedDtor();
   void SetCachedSize(int size) const final;
   void InternalSwap(Option* other);
+
+  private:
   friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
   static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
     return "google.protobuf.Option";
@@ -1343,7 +1333,7 @@
   template <typename ArgT0 = const std::string&, typename... ArgT>
   void set_name(ArgT0&& arg0, ArgT... args);
   std::string* mutable_name();
-  PROTOBUF_MUST_USE_RESULT std::string* release_name();
+  PROTOBUF_NODISCARD std::string* release_name();
   void set_allocated_name(std::string* name);
   private:
   const std::string& _internal_name() const;
@@ -1358,7 +1348,7 @@
   public:
   void clear_value();
   const ::PROTOBUF_NAMESPACE_ID::Any& value() const;
-  PROTOBUF_MUST_USE_RESULT ::PROTOBUF_NAMESPACE_ID::Any* release_value();
+  PROTOBUF_NODISCARD ::PROTOBUF_NAMESPACE_ID::Any* release_value();
   ::PROTOBUF_NAMESPACE_ID::Any* mutable_value();
   void set_allocated_value(::PROTOBUF_NAMESPACE_ID::Any* value);
   private:
diff --git a/src/google/protobuf/unittest_custom_options.proto b/src/google/protobuf/unittest_custom_options.proto
index f774c76..1812d71 100644
--- a/src/google/protobuf/unittest_custom_options.proto
+++ b/src/google/protobuf/unittest_custom_options.proto
@@ -108,6 +108,8 @@
     int32 oneof_field = 2;
   }
 
+  map<string, string> map_field = 3 [(field_opt1) = 12345];
+
   enum AnEnum {
     option (enum_opt1) = -789;
 
diff --git a/src/google/protobuf/util/message_differencer.cc b/src/google/protobuf/util/message_differencer.cc
index 65beed6..568346f 100644
--- a/src/google/protobuf/util/message_differencer.cc
+++ b/src/google/protobuf/util/message_differencer.cc
@@ -2076,9 +2076,9 @@
 void MessageDifferencer::StreamReporter::PrintMapKey(
     bool left_side, const SpecificField& specific_field) {
   if (message1_ == nullptr || message2_ == nullptr) {
-    GOOGLE_LOG(WARNING) << "PrintPath cannot log map keys; "
-                    "use SetMessages to provide the messages "
-                    "being compared prior to any processing.";
+    GOOGLE_LOG(INFO) << "PrintPath cannot log map keys; "
+                 "use SetMessages to provide the messages "
+                 "being compared prior to any processing.";
     return;
   }
 
diff --git a/src/google/protobuf/wrappers.pb.h b/src/google/protobuf/wrappers.pb.h
index 1768f7d..48609b2 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 < 3017000
+#if PROTOBUF_VERSION < 3018000
 #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 3017003 < PROTOBUF_MIN_PROTOC_VERSION
+#if 3018000 < 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.
@@ -171,11 +171,7 @@
 
   // implements Message ----------------------------------------------
 
-  inline DoubleValue* New() const final {
-    return new DoubleValue();
-  }
-
-  DoubleValue* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final {
+  DoubleValue* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final {
     return CreateMaybeMessage<DoubleValue>(arena);
   }
   using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom;
@@ -199,6 +195,8 @@
   void SharedDtor();
   void SetCachedSize(int size) const final;
   void InternalSwap(DoubleValue* other);
+
+  private:
   friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
   static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
     return "google.protobuf.DoubleValue";
@@ -319,11 +317,7 @@
 
   // implements Message ----------------------------------------------
 
-  inline FloatValue* New() const final {
-    return new FloatValue();
-  }
-
-  FloatValue* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final {
+  FloatValue* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final {
     return CreateMaybeMessage<FloatValue>(arena);
   }
   using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom;
@@ -347,6 +341,8 @@
   void SharedDtor();
   void SetCachedSize(int size) const final;
   void InternalSwap(FloatValue* other);
+
+  private:
   friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
   static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
     return "google.protobuf.FloatValue";
@@ -467,11 +463,7 @@
 
   // implements Message ----------------------------------------------
 
-  inline Int64Value* New() const final {
-    return new Int64Value();
-  }
-
-  Int64Value* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final {
+  Int64Value* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final {
     return CreateMaybeMessage<Int64Value>(arena);
   }
   using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom;
@@ -495,6 +487,8 @@
   void SharedDtor();
   void SetCachedSize(int size) const final;
   void InternalSwap(Int64Value* other);
+
+  private:
   friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
   static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
     return "google.protobuf.Int64Value";
@@ -615,11 +609,7 @@
 
   // implements Message ----------------------------------------------
 
-  inline UInt64Value* New() const final {
-    return new UInt64Value();
-  }
-
-  UInt64Value* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final {
+  UInt64Value* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final {
     return CreateMaybeMessage<UInt64Value>(arena);
   }
   using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom;
@@ -643,6 +633,8 @@
   void SharedDtor();
   void SetCachedSize(int size) const final;
   void InternalSwap(UInt64Value* other);
+
+  private:
   friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
   static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
     return "google.protobuf.UInt64Value";
@@ -763,11 +755,7 @@
 
   // implements Message ----------------------------------------------
 
-  inline Int32Value* New() const final {
-    return new Int32Value();
-  }
-
-  Int32Value* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final {
+  Int32Value* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final {
     return CreateMaybeMessage<Int32Value>(arena);
   }
   using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom;
@@ -791,6 +779,8 @@
   void SharedDtor();
   void SetCachedSize(int size) const final;
   void InternalSwap(Int32Value* other);
+
+  private:
   friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
   static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
     return "google.protobuf.Int32Value";
@@ -911,11 +901,7 @@
 
   // implements Message ----------------------------------------------
 
-  inline UInt32Value* New() const final {
-    return new UInt32Value();
-  }
-
-  UInt32Value* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final {
+  UInt32Value* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final {
     return CreateMaybeMessage<UInt32Value>(arena);
   }
   using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom;
@@ -939,6 +925,8 @@
   void SharedDtor();
   void SetCachedSize(int size) const final;
   void InternalSwap(UInt32Value* other);
+
+  private:
   friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
   static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
     return "google.protobuf.UInt32Value";
@@ -1059,11 +1047,7 @@
 
   // implements Message ----------------------------------------------
 
-  inline BoolValue* New() const final {
-    return new BoolValue();
-  }
-
-  BoolValue* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final {
+  BoolValue* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final {
     return CreateMaybeMessage<BoolValue>(arena);
   }
   using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom;
@@ -1087,6 +1071,8 @@
   void SharedDtor();
   void SetCachedSize(int size) const final;
   void InternalSwap(BoolValue* other);
+
+  private:
   friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
   static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
     return "google.protobuf.BoolValue";
@@ -1207,11 +1193,7 @@
 
   // implements Message ----------------------------------------------
 
-  inline StringValue* New() const final {
-    return new StringValue();
-  }
-
-  StringValue* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final {
+  StringValue* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final {
     return CreateMaybeMessage<StringValue>(arena);
   }
   using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom;
@@ -1235,6 +1217,8 @@
   void SharedDtor();
   void SetCachedSize(int size) const final;
   void InternalSwap(StringValue* other);
+
+  private:
   friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
   static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
     return "google.protobuf.StringValue";
@@ -1265,7 +1249,7 @@
   template <typename ArgT0 = const std::string&, typename... ArgT>
   void set_value(ArgT0&& arg0, ArgT... args);
   std::string* mutable_value();
-  PROTOBUF_MUST_USE_RESULT std::string* release_value();
+  PROTOBUF_NODISCARD std::string* release_value();
   void set_allocated_value(std::string* value);
   private:
   const std::string& _internal_value() const;
@@ -1360,11 +1344,7 @@
 
   // implements Message ----------------------------------------------
 
-  inline BytesValue* New() const final {
-    return new BytesValue();
-  }
-
-  BytesValue* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final {
+  BytesValue* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final {
     return CreateMaybeMessage<BytesValue>(arena);
   }
   using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom;
@@ -1388,6 +1368,8 @@
   void SharedDtor();
   void SetCachedSize(int size) const final;
   void InternalSwap(BytesValue* other);
+
+  private:
   friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
   static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
     return "google.protobuf.BytesValue";
@@ -1418,7 +1400,7 @@
   template <typename ArgT0 = const std::string&, typename... ArgT>
   void set_value(ArgT0&& arg0, ArgT... args);
   std::string* mutable_value();
-  PROTOBUF_MUST_USE_RESULT std::string* release_value();
+  PROTOBUF_NODISCARD std::string* release_value();
   void set_allocated_value(std::string* value);
   private:
   const std::string& _internal_value() const;
diff --git a/tests.sh b/tests.sh
index 1955b7b..71635f9 100755
--- a/tests.sh
+++ b/tests.sh
@@ -88,6 +88,18 @@
 }
 
 build_dist_install() {
+  # Create a symlink pointing to python2 and put it at the beginning of $PATH.
+  # This is necessary because the googletest build system involves a Python
+  # script that is not compatible with Python 3. More recent googletest
+  # versions have fixed this, but they have also removed the autotools build
+  # system support that we rely on. This is a temporary workaround to keep the
+  # googletest build working when the default python binary is Python 3.
+  mkdir tmp || true
+  pushd tmp
+  ln -s /usr/bin/python2 ./python
+  popd
+  PATH=$PWD/tmp:$PATH
+
   # Initialize any submodules.
   git submodule update --init --recursive
   ./autogen.sh
@@ -112,8 +124,8 @@
   virtualenv --no-site-packages venv
   source venv/bin/activate
   pushd python
-  python setup.py clean build sdist
-  pip install dist/protobuf-*.tar.gz
+  python3 setup.py clean build sdist
+  pip3 install dist/protobuf-*.tar.gz
   popd
   deactivate
   rm -rf python/venv
diff --git a/update_version.py b/update_version.py
index 9cf1dbf..b96f715 100755
--- a/update_version.py
+++ b/update_version.py
@@ -358,6 +358,13 @@
       line))
 
 def UpdateRuby():
+  RewriteXml('ruby/pom.xml',
+             lambda document : ReplaceText(
+                 Find(document.documentElement, 'version'), GetFullVersion()))
+  RewriteXml('ruby/pom.xml',
+             lambda document : ReplaceText(
+                 Find(Find(Find(document.documentElement, 'dependencies'), 'dependency'), 'version'),
+                 GetFullVersion()))
   RewriteTextFile('ruby/google-protobuf.gemspec',
     lambda line : re.sub(
       r'^  s.version     = ".*"$',