Merge branch 'master' into integration
diff --git a/Makefile.am b/Makefile.am
index 688486b..ff4c2b1 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -951,6 +951,7 @@
   ruby/tests/test_ruby_package.proto                                         \
   ruby/tests/generated_code_test.rb                                          \
   ruby/tests/well_known_types_test.rb                                        \
+  ruby/tests/type_errors.rb                                                  \
   ruby/travis-test.sh
 
 js_EXTRA_DIST=                                                         \
diff --git a/benchmarks/Makefile.am b/benchmarks/Makefile.am
index 6f63a4c..8118365 100644
--- a/benchmarks/Makefile.am
+++ b/benchmarks/Makefile.am
@@ -126,7 +126,7 @@
 	java/src/main/java/com/google/protobuf/ProtoCaliperBenchmark.java
 
 javac_middleman: $(java_benchmark_testing_files) protoc_middleman protoc_middleman2
-	cp -r $(srcdir)/java tmp 
+	cp -r $(srcdir)/java tmp
 	mkdir -p tmp/java/lib
 	cp $(top_srcdir)/java/core/target/*.jar tmp/java/lib/protobuf-java.jar
 	cd tmp/java && mvn clean compile assembly:single -Dprotobuf.version=$(PACKAGE_VERSION) && cd ../..
@@ -253,7 +253,7 @@
 	oldpwd=`pwd` && ( cd $(srcdir) && $$oldpwd/../src/protoc$(EXEEXT) -I. -I$(top_srcdir)/src --go_out=$$oldpwd/tmp $(benchmarks_protoc_inputs_proto2_message4) )
 	touch go_protoc_middleman
 
-go-benchmark: go_protoc_middleman 
+go-benchmark: go_protoc_middleman
 	@echo "Writing shortcut script go-benchmark..."
 	@echo '#! /bin/bash' > go-benchmark
 	@echo 'cd $(srcdir)/go' >> go-benchmark
@@ -265,7 +265,7 @@
 	@echo 'cd ..' >> go-benchmark
 	@chmod +x go-benchmark
 
-go: go_protoc_middleman go-benchmark 
+go: go_protoc_middleman go-benchmark
 	./go-benchmark $(all_data)
 
 ############# GO RULES END ##############
@@ -322,9 +322,9 @@
 generate_cpp_no_group_benchmark_code:
 	cp $(srcdir)/cpp/cpp_benchmark.cc gogo/cpp_no_group/cpp_benchmark.cc
 	sed -i -e "s/\#include \"datasets/\#include \"gogo\/cpp_no_group\/datasets/g" gogo/cpp_no_group/cpp_benchmark.cc
-	sed -i -e "s/\#include \"benchmarks.pb.h/\#include \"gogo\/cpp_no_group\/benchmarks.pb.h/g" gogo/cpp_no_group/cpp_benchmark.cc  
+	sed -i -e "s/\#include \"benchmarks.pb.h/\#include \"gogo\/cpp_no_group\/benchmarks.pb.h/g" gogo/cpp_no_group/cpp_benchmark.cc
 	touch generate_cpp_no_group_benchmark_code
-	
+
 bin_PROGRAMS += cpp-no-group-benchmark
 cpp_no_group_benchmark_LDADD = $(top_srcdir)/src/libprotobuf.la $(top_srcdir)/third_party/benchmark/src/libbenchmark.a
 cpp_no_group_benchmark_SOURCES = gogo/cpp_no_group/cpp_benchmark.cc
@@ -343,7 +343,7 @@
 
 cpp_no_group: cpp_no_group_protoc_middleman generate_gogo_data cpp-no-group-benchmark
 	./cpp-no-group-benchmark $(gogo_data)
- 
+
 gogo_proto_middleman: protoc-gen-gogoproto
 	mkdir -p "tmp/gogo_proto"
 	oldpwd=`pwd` && ( cd $(srcdir) && $$oldpwd/../src/protoc$(EXEEXT) -I$(srcdir) -I$(top_srcdir) --plugin=protoc-gen-gogoproto --gogoproto_out=$$oldpwd/tmp/gogo_proto $(benchmarks_protoc_inputs) $(benchmarks_protoc_inputs_benchmark_wrapper) $(benchmarks_protoc_inputs_proto2) )
@@ -355,7 +355,7 @@
 	mkdir -p `dirname $(gogo_data)`
 	./gogo-data-scrubber $(all_data) $(gogo_data)
 	touch generate_gogo_data
-	
+
 make_tmp_dir_gogo:
 	mkdir -p tmp/go_no_group/benchmark_code
 	mkdir -p tmp/gogofast/benchmark_code
@@ -435,10 +435,10 @@
 
 go_no_group: go_no_group_protoc_middleman generate_gogo_data generate_all_gogo_benchmark_code gogo-benchmark
 	./gogo-benchmark go_no_group $(gogo_data)
-	
-gogofast: gogofast_protoc_middleman generate_gogo_data gogo-benchmark generate_all_gogo_benchmark_code 
+
+gogofast: gogofast_protoc_middleman generate_gogo_data gogo-benchmark generate_all_gogo_benchmark_code
 	./gogo-benchmark gogofast $(gogo_data)
-	
+
 gogofaster: gogofaster_protoc_middleman  generate_gogo_data gogo-benchmark generate_all_gogo_benchmark_code
 	./gogo-benchmark gogofaster $(gogo_data)
 
@@ -448,7 +448,7 @@
 
 ############# GOGO RULES END ############
 
- 
+
 ############ UTIL RULES BEGIN ############
 
 bin_PROGRAMS += protoc-gen-gogoproto gogo-data-scrubber protoc-gen-proto2_to_proto3 proto3-data-stripper
@@ -481,7 +481,7 @@
 	$(benchmarks_protoc_outputs_proto2_header)                               \
 	$(benchmarks_protoc_outputs_header)
 
-	
+
 ############ UTIL RULES END ############
 
 ############ PROTO3 PREPARATION BEGIN #############
@@ -510,7 +510,7 @@
 
 php-benchmark: proto3_middleman_php generate_proto3_data
 	mkdir -p "tmp/php/Google/Protobuf/Benchmark" && cp php/PhpBenchmark.php "tmp/php/Google/Protobuf/Benchmark"
-	cp php/autoload.php "tmp/php"  
+	cp php/autoload.php "tmp/php"
 	@echo "Writing shortcut script php-benchmark..."
 	@echo '#! /bin/bash' > php-benchmark
 	@echo 'export PROTOBUF_PHP_SRCDIR="$$(cd $(top_srcdir) && pwd)/php/src"' >> php-benchmark
@@ -527,8 +527,8 @@
 	cd $(top_srcdir)/php/ext/google/protobuf && phpize && ./configure CFLAGS='-O3' && make -j8
 
 php-c-benchmark: proto3_middleman_php generate_proto3_data php_c_extension php_c_extension
-	mkdir -p "tmp/php/Google/Protobuf/Benchmark" && cp php/PhpBenchmark.php "tmp/php/Google/Protobuf/Benchmark" 
-	cp php/autoload.php "tmp/php"  
+	mkdir -p "tmp/php/Google/Protobuf/Benchmark" && cp php/PhpBenchmark.php "tmp/php/Google/Protobuf/Benchmark"
+	cp php/autoload.php "tmp/php"
 	@echo "Writing shortcut script php-c-benchmark..."
 	@echo '#! /bin/bash' > php-c-benchmark
 	@echo 'export PROTOBUF_PHP_SRCDIR="$$(cd $(top_srcdir) && pwd)/php/src"' >> php-c-benchmark
@@ -654,4 +654,4 @@
 
 clean-local:
 	-rm -rf tmp/*
-	
+
diff --git a/benchmarks/README.md b/benchmarks/README.md
index 72885886..486b2f9 100644
--- a/benchmarks/README.md
+++ b/benchmarks/README.md
@@ -3,7 +3,7 @@
 
 This directory contains benchmarking schemas and data sets that you
 can use to test a variety of performance scenarios against your
-protobuf language runtime. If you are looking for performance 
+protobuf language runtime. If you are looking for performance
 numbers of officially support languages, see [here](
 https://github.com/protocolbuffers/protobuf/blob/master/docs/performance.md)
 
@@ -45,8 +45,8 @@
 
 ### Go
 Go protobufs are maintained at [github.com/golang/protobuf](
-http://github.com/golang/protobuf). If not done already, you need to install the 
-toolchain and the Go protoc-gen-go plugin for protoc. 
+http://github.com/golang/protobuf). If not done already, you need to install the
+toolchain and the Go protoc-gen-go plugin for protoc.
 
 To install protoc-gen-go, run:
 
@@ -59,7 +59,7 @@
 The second command adds the `bin` directory to your `PATH` so that `protoc` can locate the plugin later.
 
 ### PHP
-PHP benchmark's requirement is the same as PHP protobuf's requirements. The benchmark will automaticly 
+PHP benchmark's requirement is the same as PHP protobuf's requirements. The benchmark will automaticly
 include PHP protobuf's src and build the c extension if required.
 
 ### Node.js
diff --git a/benchmarks/java/src/main/java/com/google/protobuf/ProtoCaliperBenchmark.java b/benchmarks/java/src/main/java/com/google/protobuf/ProtoCaliperBenchmark.java
index c766d74..a440248 100644
--- a/benchmarks/java/src/main/java/com/google/protobuf/ProtoCaliperBenchmark.java
+++ b/benchmarks/java/src/main/java/com/google/protobuf/ProtoCaliperBenchmark.java
@@ -24,8 +24,8 @@
 import java.util.List;
 
 // Caliper set CICompilerCount to 1 for making sure compilation doesn't run in parallel with itself,
-// This makes TieredCompilation not working. We just disable TieredCompilation by default. In master 
-// branch this has been disabled by default in caliper: 
+// This makes TieredCompilation not working. We just disable TieredCompilation by default. In master
+// branch this has been disabled by default in caliper:
 // https://github.com/google/caliper/blob/master/caliper-runner/src/main/java/com/google/caliper/runner/target/Jvm.java#L38:14
 // But this haven't been added into most recent release.
 @VmOptions("-XX:-TieredCompilation")
@@ -89,7 +89,7 @@
         return com.google.protobuf.benchmarks.BenchmarkMessage4.GoogleMessage4.getDefaultInstance();
       }
     };
-    
+
     abstract ExtensionRegistry getExtensionRegistry();
     abstract Message getDefaultInstance();
   }
@@ -97,7 +97,7 @@
   private BenchmarkMessageType benchmarkMessageType;
   @Param("")
   private String dataFile;
-  
+
   private byte[] inputData;
   private BenchmarkDataset benchmarkDataset;
   private Message defaultMessage;
@@ -125,7 +125,7 @@
           + benchmarkDataset.getMessageName());
     }
   }
-  
+
   @BeforeExperiment
   void setUp() throws IOException {
     if (!dataFile.equals("")) {
@@ -145,7 +145,7 @@
     inputStreamList = new ArrayList<ByteArrayInputStream>();
     inputStringList = new ArrayList<ByteString>();
     sampleMessageList = new ArrayList<Message>();
-    
+
     for (int i = 0; i < benchmarkDataset.getPayloadCount(); i++) {
       byte[] singleInputData = benchmarkDataset.getPayload(i).toByteArray();
       inputDataList.add(benchmarkDataset.getPayload(i).toByteArray());
@@ -156,8 +156,8 @@
           defaultMessage.newBuilderForType().mergeFrom(singleInputData, extensions).build());
     }
   }
-  
-  
+
+
   @Benchmark
   void serializeToByteArray(int reps) throws IOException {
     if (sampleMessageList.size() == 0) {
@@ -165,11 +165,11 @@
     }
     for (int i = 0; i < reps; i++) {
       for (int j = 0; j < sampleMessageList.size(); j++) {
-        sampleMessageList.get(j).toByteArray();  
+        sampleMessageList.get(j).toByteArray();
       }
     }
   }
-  
+
   @Benchmark
   void serializeToMemoryStream(int reps) throws IOException {
     if (sampleMessageList.size() == 0) {
@@ -178,11 +178,11 @@
     for (int i = 0; i < reps; i++) {
       for (int j = 0; j < sampleMessageList.size(); j++) {
         ByteArrayOutputStream output = new ByteArrayOutputStream();
-        sampleMessageList.get(j).writeTo(output); 
+        sampleMessageList.get(j).writeTo(output);
       }
     }
   }
-  
+
   @Benchmark
   void deserializeFromByteArray(int reps) throws IOException {
     if (inputDataList.size() == 0) {
@@ -195,7 +195,7 @@
       }
     }
   }
-  
+
   @Benchmark
   void deserializeFromMemoryStream(int reps) throws IOException {
     if (inputStreamList.size() == 0) {
diff --git a/benchmarks/js/benchmark_suite.js b/benchmarks/js/benchmark_suite.js
index c95024b..c5c3e51 100644
--- a/benchmarks/js/benchmark_suite.js
+++ b/benchmarks/js/benchmark_suite.js
@@ -9,8 +9,8 @@
       })
       .on("start", function() {
           process.stdout.write(
-            "benchmarking message " + messageName 
-            + " of dataset file " + filename 
+            "benchmarking message " + messageName
+            + " of dataset file " + filename
             + "'s performance ..." + "\n\n");
       })
       .on("cycle", function(event) {
@@ -21,7 +21,7 @@
             return 1 / (bench.stats.mean + bench.stats.moe);
           }
           benches.forEach(function(val, index) {
-            benches[index] = getHz(val); 
+            benches[index] = getHz(val);
           });
       }),
      benches: benches
diff --git a/benchmarks/js/js_benchmark.js b/benchmarks/js/js_benchmark.js
index 875be68..c44fee0 100644
--- a/benchmarks/js/js_benchmark.js
+++ b/benchmarks/js/js_benchmark.js
@@ -30,7 +30,7 @@
     json_file = filename.replace(/^--json_output=/, '');
     return;
   }
-  
+
   var benchmarkDataset =
       proto.benchmarks.BenchmarkDataset.deserializeBinary(fs.readFileSync(filename));
   var messageList = [];
@@ -40,7 +40,7 @@
     messageList.push(message.deserializeBinary(onePayload));
     totalBytes += onePayload.length;
   });
-  
+
   var senarios = benchmarkSuite.newBenchmark(
       benchmarkDataset.getMessageName(), filename, "js");
   senarios.suite
@@ -48,14 +48,14 @@
     benchmarkDataset.getPayloadList().forEach(function(onePayload) {
       var protoType = getNewPrototype(benchmarkDataset.getMessageName());
       protoType.deserializeBinary(onePayload);
-    });    
+    });
   })
   .add("js serialize", function() {
     var protoType = getNewPrototype(benchmarkDataset.getMessageName());
     messageList.forEach(function(message) {
       message.serializeBinary();
     });
-  }) 
+  })
   .run({"Async": false});
 
   results.push({
@@ -66,9 +66,9 @@
     }
   })
 
-  console.log("Throughput for deserialize: " 
+  console.log("Throughput for deserialize: "
     + senarios.benches[0] * totalBytes / 1024 / 1024 + "MB/s" );
-  console.log("Throughput for serialize: " 
+  console.log("Throughput for serialize: "
     + senarios.benches[1] * totalBytes / 1024 / 1024 + "MB/s" );
   console.log("");
 });
diff --git a/benchmarks/php/PhpBenchmark.php b/benchmarks/php/PhpBenchmark.php
index 2c5245d..d3db61d 100644
--- a/benchmarks/php/PhpBenchmark.php
+++ b/benchmarks/php/PhpBenchmark.php
@@ -33,7 +33,7 @@
             (new $args[1]())->mergeFromString($payloads->offsetGet($i));
         }
     }
-    
+
     // $args: array of message
     static function serialize(&$args) {
         foreach ($args as &$temp_message) {
@@ -49,7 +49,7 @@
     private $benchmark_time;
     private $total_bytes;
     private $coefficient;
-    
+
     public function __construct($benchmark_name, $args, $total_bytes,
         $benchmark_time = 5.0) {
             $this->args = $args;
@@ -58,7 +58,7 @@
             $this->total_bytes = $total_bytes;
             $this->coefficient = pow (10, 0) / pow(2, 20);
     }
-    
+
     public function runBenchmark() {
         $t = $this->runBenchmarkWithTimes(1);
         $times = ceil($this->benchmark_time / $t);
@@ -66,7 +66,7 @@
         ($times == 1 ? $t : $this->runBenchmarkWithTimes($times)) *
         $this->coefficient;
     }
-    
+
     private function runBenchmarkWithTimes($times) {
         $st = microtime(true);
         for ($i = 0; $i < $times; $i++) {
@@ -109,14 +109,14 @@
         array_push($message_list, $new_message);
         $total_bytes += strlen($payloads->offsetGet($i));
     }
-    
+
     $parse_benchmark = new Benchmark(
         "\Google\Protobuf\Benchmark\BenchmarkMethod::parse",
         array($dataset, $message_name), $total_bytes);
     $serialize_benchmark = new Benchmark(
         "\Google\Protobuf\Benchmark\BenchmarkMethod::serialize",
         $message_list, $total_bytes);
-    
+
     return array(
         "filename" => $file,
         "benchmarks" => array(
@@ -139,7 +139,7 @@
     if ($arg == "--json") {
         $json_output = true;
     } else if (strpos($arg, "--behavior_prefix") == 0) {
-        $behavior_prefix = str_replace("--behavior_prefix=", "", $arg);     
+        $behavior_prefix = str_replace("--behavior_prefix=", "", $arg);
     }
 }
 
diff --git a/benchmarks/protobuf.js/protobufjs_benchmark.js b/benchmarks/protobuf.js/protobufjs_benchmark.js
index 2629e9f..19e5497 100644
--- a/benchmarks/protobuf.js/protobufjs_benchmark.js
+++ b/benchmarks/protobuf.js/protobufjs_benchmark.js
@@ -30,7 +30,7 @@
     messageList.push(message.decode(onePayload));
     totalBytes += onePayload.length;
   });
-  
+
   var senarios = benchmarkSuite.newBenchmark(
     benchmarkDataset.messageName, filename, "protobufjs");
   senarios.suite
@@ -38,14 +38,14 @@
     benchmarkDataset.payload.forEach(function(onePayload) {
       var protoType = getNewPrototype(benchmarkDataset.messageName);
       protoType.decode(onePayload);
-    });    
+    });
   })
   .add("protobuf.js static encoding", function() {
     var protoType = getNewPrototype(benchmarkDataset.messageName);
     messageList.forEach(function(message) {
       protoType.encode(message).finish();
     });
-  }) 
+  })
   .run({"Async": false});
 
   results.push({
@@ -56,9 +56,9 @@
     }
   })
 
-  console.log("Throughput for decoding: " 
+  console.log("Throughput for decoding: "
     + senarios.benches[0] * totalBytes / 1024 / 1024 + "MB/s" );
-  console.log("Throughput for encoding: " 
+  console.log("Throughput for encoding: "
     + senarios.benches[1] * totalBytes / 1024 / 1024 + "MB/s" );
   console.log("");
 });
diff --git a/benchmarks/python/py_benchmark.py b/benchmarks/python/py_benchmark.py
index d29175e..f2c7bcc 100755
--- a/benchmarks/python/py_benchmark.py
+++ b/benchmarks/python/py_benchmark.py
@@ -8,7 +8,7 @@
 import json
 
 parser = argparse.ArgumentParser(description="Python protobuf benchmark")
-parser.add_argument("data_files", metavar="dataFile", nargs="+", 
+parser.add_argument("data_files", metavar="dataFile", nargs="+",
                     help="testing data files.")
 parser.add_argument("--json", action="store_const", dest="json",
                     const="yes", default="no",
@@ -138,14 +138,14 @@
         t = timeit.timeit(stmt="%s(%s)" % (self.test_method, test_method_args),
                           setup=self.full_setup_code(setup_method_args),
                           number=reps);
-    return self.total_bytes * 1.0 / 2 ** 20 / (1.0 * t / reps * self.full_iteration)  
-  
+    return self.total_bytes * 1.0 / 2 ** 20 / (1.0 * t / reps * self.full_iteration)
+
 
 if __name__ == "__main__":
   results = []
   for file in args.data_files:
     results.append(run_one_test(file))
-  
+
   if args.json != "no":
     print(json.dumps(results))
   else:
diff --git a/benchmarks/util/result_parser.py b/benchmarks/util/result_parser.py
index 8f26dd2..e3d8e42 100755
--- a/benchmarks/util/result_parser.py
+++ b/benchmarks/util/result_parser.py
@@ -295,6 +295,6 @@
   if php_file != "":
     __parse_php_result(php_file, "php")
   if php_c_file != "":
-    __parse_php_result(php_c_file, "php")        
+    __parse_php_result(php_c_file, "php")
 
   return __results
diff --git a/benchmarks/util/result_uploader.py b/benchmarks/util/result_uploader.py
index 021cc54..2a35d96 100755
--- a/benchmarks/util/result_uploader.py
+++ b/benchmarks/util/result_uploader.py
@@ -60,7 +60,7 @@
     new_result["labels"] = labels_string[1:]
     new_result["timestamp"] = _INITIAL_TIME
     print(labels_string)
- 
+
     bq = big_query_utils.create_big_query()
     row = big_query_utils.make_row(str(uuid.uuid4()), new_result)
     if not big_query_utils.insert_rows(bq, _PROJECT_ID, _DATASET,
@@ -91,7 +91,7 @@
                       default="")
   parser.add_argument("-php_c", "--php_c_input_file",
                       help="The php with c ext benchmark result file's name",
-                      default="")    
+                      default="")
   args = parser.parse_args()
 
   metadata = get_metadata()
diff --git a/cmake/README.md b/cmake/README.md
index 29f7669..96aaf4f 100644
--- a/cmake/README.md
+++ b/cmake/README.md
@@ -130,11 +130,11 @@
 If the *gmock* directory does not exist, and you do not want to build protobuf unit tests,
 you need to add *cmake* command argument `-Dprotobuf_BUILD_TESTS=OFF` to disable testing.
 
-To make a *Visual Studio* file for Visual Studio 15 2017, create the *Visual Studio* 
+To make a *Visual Studio* file for Visual Studio 15 2017, create the *Visual Studio*
 solution file above and edit the CmakeCache file.
-	
+
 	C:Path\to\protobuf\cmake\build\solution\CMakeCache
-	
+
 Then create the *Visual Studio* solution file again
 
 Compiling
@@ -177,9 +177,9 @@
 
      Running main() from gmock_main.cc
      [==========] Running 1546 tests from 165 test cases.
-     
+
      ...
-     
+
      [==========] 1546 tests from 165 test cases ran. (2529 ms total)
      [  PASSED  ] 1546 tests.
 
@@ -198,7 +198,7 @@
      [ RUN      ] AnyTest.TestIs
      [       OK ] AnyTest.TestIs (0 ms)
      [----------] 3 tests from AnyTest (1 ms total)
-     
+
      [----------] Global test environment tear-down
      [==========] 3 tests from 1 test case ran. (2 ms total)
      [  PASSED  ] 3 tests.
@@ -310,7 +310,7 @@
 
 	-DZLIB_INCLUDE_DIR=<path to dir containing zlib headers>
 	-DZLIB_LIB=<path to dir containing zlib>
-	
+
 Build and testing protobuf as usual.
 
 Notes on Compiler Warnings
diff --git a/cmake/protobuf-config.cmake.in b/cmake/protobuf-config.cmake.in
index 1805468..29e39d8 100644
--- a/cmake/protobuf-config.cmake.in
+++ b/cmake/protobuf-config.cmake.in
@@ -37,7 +37,7 @@
   if(NOT protobuf_generate_PROTOC_OUT_DIR)
     set(protobuf_generate_PROTOC_OUT_DIR ${CMAKE_CURRENT_BINARY_DIR})
   endif()
-  
+
   if(protobuf_generate_EXPORT_MACRO AND protobuf_generate_LANGUAGE STREQUAL cpp)
     set(_dll_export_decl "dllexport_decl=${protobuf_generate_EXPORT_MACRO}:")
   endif()
diff --git a/cmake/version.rc.in b/cmake/version.rc.in
index cbce1e5..aeeaadf 100644
--- a/cmake/version.rc.in
+++ b/cmake/version.rc.in
@@ -23,7 +23,7 @@
   FILETYPE       VFT_DLL
 BEGIN
     BLOCK "VarFileInfo"
-    BEGIN 
+    BEGIN
         // English language (0x409) and the Windows Unicode codepage (1200)
         VALUE "Translation", 0x409, 1200
     END
diff --git a/conformance/ConformanceJava.java b/conformance/ConformanceJava.java
index 478b186..c5b3f4e 100644
--- a/conformance/ConformanceJava.java
+++ b/conformance/ConformanceJava.java
@@ -57,7 +57,7 @@
     buf[3] = (byte)(val >> 24);
     writeToStdout(buf);
   }
-  
+
   private enum BinaryDecoderType {
     BTYE_STRING_DECODER,
     BYTE_ARRAY_DECODER,
@@ -69,11 +69,11 @@
   }
 
   private static class BinaryDecoder <MessageType extends AbstractMessage> {
-    public MessageType decode (ByteString bytes, BinaryDecoderType type, 
+    public MessageType decode (ByteString bytes, BinaryDecoderType type,
         Parser <MessageType> parser, ExtensionRegistry extensions)
       throws InvalidProtocolBufferException {
       switch (type) {
-        case BTYE_STRING_DECODER: 
+        case BTYE_STRING_DECODER:
           return parser.parseFrom(bytes, extensions);
         case BYTE_ARRAY_DECODER:
           return parser.parseFrom(bytes.toByteArray(), extensions);
@@ -94,7 +94,7 @@
           } catch (InvalidProtocolBufferException e) {
             throw e;
           }
-        } 
+        }
         case DIRECT_BYTE_BUFFER_DECODER: {
           ByteBuffer buffer = ByteBuffer.allocateDirect(bytes.size());
           bytes.copyTo(buffer);
@@ -135,7 +135,7 @@
     ArrayList <MessageType> messages = new ArrayList <MessageType> ();
     ArrayList <InvalidProtocolBufferException> exceptions =
         new ArrayList <InvalidProtocolBufferException>();
-    
+
     for (int i = 0; i < BinaryDecoderType.values().length; i++) {
       messages.add(null);
       exceptions.add(null);
@@ -290,7 +290,7 @@
         throw new RuntimeException("Unspecified output format.");
 
       case PROTOBUF: {
-        ByteString MessageString = testMessage.toByteString(); 
+        ByteString MessageString = testMessage.toByteString();
         return Conformance.ConformanceResponse.newBuilder().setProtobufPayload(MessageString).build();
       }
 
diff --git a/conformance/conformance_ruby.rb b/conformance/conformance_ruby.rb
index df63bf7..0e2126e 100755
--- a/conformance/conformance_ruby.rb
+++ b/conformance/conformance_ruby.rb
@@ -54,7 +54,7 @@
       elsif request.message_type.eql?('protobuf_test_messages.proto2.TestAllTypesProto2')
         response.skipped = "Ruby doesn't support proto2"
         return response
-      else 
+      else
         fail "Protobuf request doesn't have specific payload type"
       end
 
diff --git a/conformance/third_party/jsoncpp/json.h b/conformance/third_party/jsoncpp/json.h
index 42e7e7f..32fd072 100644
--- a/conformance/third_party/jsoncpp/json.h
+++ b/conformance/third_party/jsoncpp/json.h
@@ -6,28 +6,28 @@
 // //////////////////////////////////////////////////////////////////////
 
 /*
-The JsonCpp library's source code, including accompanying documentation, 
+The JsonCpp library's source code, including accompanying documentation,
 tests and demonstration applications, are licensed under the following
 conditions...
 
-The author (Baptiste Lepilleur) explicitly disclaims copyright in all 
-jurisdictions which recognize such a disclaimer. In such jurisdictions, 
+The author (Baptiste Lepilleur) explicitly disclaims copyright in all
+jurisdictions which recognize such a disclaimer. In such jurisdictions,
 this software is released into the Public Domain.
 
 In jurisdictions which do not recognize Public Domain property (e.g. Germany as of
 2010), this software is Copyright (c) 2007-2010 by Baptiste Lepilleur, and is
 released under the terms of the MIT License (see below).
 
-In jurisdictions which recognize Public Domain property, the user of this 
-software may choose to accept it either as 1) Public Domain, 2) under the 
-conditions of the MIT License (see below), or 3) under the terms of dual 
+In jurisdictions which recognize Public Domain property, the user of this
+software may choose to accept it either as 1) Public Domain, 2) under the
+conditions of the MIT License (see below), or 3) under the terms of dual
 Public Domain/MIT License conditions described here, as they choose.
 
 The MIT License is about as close to Public Domain as a license can get, and is
 described in clear, concise terms at:
 
    http://en.wikipedia.org/wiki/MIT_License
-   
+
 The full text of the MIT License follows:
 
 ========================================================================
@@ -434,7 +434,7 @@
 /** Exceptions which the user cannot easily avoid.
  *
  * E.g. out-of-memory (when we use malloc), stack-overflow, malicious input
- * 
+ *
  * \remark derived from Json::Exception
  */
 class JSON_API RuntimeError : public Exception {
@@ -445,7 +445,7 @@
 /** Exceptions thrown by JSON_ASSERT/JSON_FAIL macros.
  *
  * These are precondition-violations (user bugs) and internal errors (our bugs).
- * 
+ *
  * \remark derived from Json::Exception
  */
 class JSON_API LogicError : public Exception {
@@ -1570,7 +1570,7 @@
     - `"rejectDupKeys": false or true`
       - If true, `parse()` returns false when a key is duplicated within an object.
     - `"allowSpecialFloats": false or true`
-      - If true, special float values (NaNs and infinities) are allowed 
+      - If true, special float values (NaNs and infinities) are allowed
         and their values are lossfree restorable.
 
     You can examine 'settings_` yourself
diff --git a/conformance/third_party/jsoncpp/jsoncpp.cpp b/conformance/third_party/jsoncpp/jsoncpp.cpp
index f803962..4d3e0f2 100644
--- a/conformance/third_party/jsoncpp/jsoncpp.cpp
+++ b/conformance/third_party/jsoncpp/jsoncpp.cpp
@@ -6,28 +6,28 @@
 // //////////////////////////////////////////////////////////////////////
 
 /*
-The JsonCpp library's source code, including accompanying documentation, 
+The JsonCpp library's source code, including accompanying documentation,
 tests and demonstration applications, are licensed under the following
 conditions...
 
-The author (Baptiste Lepilleur) explicitly disclaims copyright in all 
-jurisdictions which recognize such a disclaimer. In such jurisdictions, 
+The author (Baptiste Lepilleur) explicitly disclaims copyright in all
+jurisdictions which recognize such a disclaimer. In such jurisdictions,
 this software is released into the Public Domain.
 
 In jurisdictions which do not recognize Public Domain property (e.g. Germany as of
 2010), this software is Copyright (c) 2007-2010 by Baptiste Lepilleur, and is
 released under the terms of the MIT License (see below).
 
-In jurisdictions which recognize Public Domain property, the user of this 
-software may choose to accept it either as 1) Public Domain, 2) under the 
-conditions of the MIT License (see below), or 3) under the terms of dual 
+In jurisdictions which recognize Public Domain property, the user of this
+software may choose to accept it either as 1) Public Domain, 2) under the
+conditions of the MIT License (see below), or 3) under the terms of dual
 Public Domain/MIT License conditions described here, as they choose.
 
 The MIT License is about as close to Public Domain as a license can get, and is
 described in clear, concise terms at:
 
    http://en.wikipedia.org/wiki/MIT_License
-   
+
 The full text of the MIT License follows:
 
 ========================================================================
@@ -207,7 +207,7 @@
 #include <limits>
 
 #if defined(_MSC_VER)
-#if !defined(WINCE) && defined(__STDC_SECURE_LIB__) && _MSC_VER >= 1500 // VC++ 9.0 and above 
+#if !defined(WINCE) && defined(__STDC_SECURE_LIB__) && _MSC_VER >= 1500 // VC++ 9.0 and above
 #define snprintf sprintf_s
 #elif _MSC_VER >= 1900 // VC++ 14.0 and above
 #define snprintf std::snprintf
@@ -4029,7 +4029,7 @@
 #define snprintf std::snprintf
 #endif
 
-#if defined(__BORLANDC__)  
+#if defined(__BORLANDC__)
 #include <float.h>
 #define isfinite _finite
 #define snprintf _snprintf
@@ -5096,7 +5096,7 @@
   std::string cs_str = settings_["commentStyle"].asString();
   bool eyc = settings_["enableYAMLCompatibility"].asBool();
   bool dnp = settings_["dropNullPlaceholders"].asBool();
-  bool usf = settings_["useSpecialFloats"].asBool(); 
+  bool usf = settings_["useSpecialFloats"].asBool();
   unsigned int pre = settings_["precision"].asUInt();
   CommentStyle::Enum cs = CommentStyle::All;
   if (cs_str == "All") {
diff --git a/csharp/CHANGES.txt b/csharp/CHANGES.txt
index a87cd4d..8574b7c 100644
--- a/csharp/CHANGES.txt
+++ b/csharp/CHANGES.txt
@@ -26,7 +26,7 @@
 - Optimized enum parsing.
 
 Fixes:
-- Fix for bug in limited input stream's Position, Introduced Position on 
+- Fix for bug in limited input stream's Position, Introduced Position on
   output stream
 - Fix for writing a character to a JSON output overflows allocated buffer
 - Optimize FromBase64String to return Empty when presented with empty string.
@@ -47,14 +47,14 @@
 - Added 'Unsafe' static type in ByteString to allow direct buffer access
 
 Fixes:
-- Issue 50: The XML serializer will fail to deserialize a message with empty 
+- Issue 50: The XML serializer will fail to deserialize a message with empty
   child message
 - Issue 45: Use of 'item' as a field name causes AmbiguousMatchException
 - Issue 49: Generated nested static Types class should be partial
 - Issue 38: Disable CLSCompliant warnings (3021)
 - Issue 40: proto_path does not work for command-line file names
 - Issue 54: should retire all bytes in buffer (bufferSize)
-- Issue 43: Fix to correct identical 'umbrella_classname' options from trying 
+- Issue 43: Fix to correct identical 'umbrella_classname' options from trying
   to write to the same filename.
 
 ===============================================================================
@@ -66,7 +66,7 @@
   NONE, GENERIC, INTERFACE, or IRPCDISPATCH
 - Added interfaces IRpcDispatch and IRpcServerStub to provide for blocking
   services and implementations.
-- Added ProtoGen.exe command-line argument "--protoc_dir=" to specify the 
+- Added ProtoGen.exe command-line argument "--protoc_dir=" to specify the
   location of protoc.exe.
 - Extracted interfaces for ICodedInputStream and ICodedOutputStream to allow
   custom implementation of writers with both speed and size optimizations.
@@ -86,9 +86,9 @@
 - Issue 16:	Does not integrate well with other tooling
 - Issue 19:	Support for negative enum values
 - Issue 26:	AddRange in GeneratedBuilder iterates twice.
-- Issue 27:	Remove XML documentation output from test projects to clear 
+- Issue 27:	Remove XML documentation output from test projects to clear
   warnings/errors.
-- Issue 28: Circular message dependencies result in null default values for 
+- Issue 28: Circular message dependencies result in null default values for
   Message fields.
 - Issue 29: Message classes generated have a public default constructor.  You
   can disable private ctor generation with the option generate_private_ctor.
@@ -109,14 +109,14 @@
 ===============================================================================
 
 Features:
-- Added cls_compliance option to generate attributes indicating 
+- Added cls_compliance option to generate attributes indicating
   non-CLS-compliance.
 - Added file_extension option to control the generated output file's extension.
 - Added umbrella_namespace option to place the umbrella class into a nested
-  namespace to address issues with proto files having the same name as a 
+  namespace to address issues with proto files having the same name as a
   message it contains.
 - Added output_directory option to set the output path for the source file(s).
-- Added ignore_google_protobuf option to avoid generating code for includes 
+- Added ignore_google_protobuf option to avoid generating code for includes
   from the google.protobuf package.
 - Added the LITE framework (Google.ProtoBuffersLite.dll) and the ability to
   generate code with "option optimize_for = LITE_RUNTIME;".
diff --git a/csharp/README.md b/csharp/README.md
index aafef16..9aab782 100644
--- a/csharp/README.md
+++ b/csharp/README.md
@@ -10,7 +10,7 @@
 contains precompiled version of `protoc.exe` and a copy of well known `.proto`
 files under the package's `tools` directory.
 
-To generate C# files from your `.proto` files, invoke `protoc` with the 
+To generate C# files from your `.proto` files, invoke `protoc` with the
 `--csharp_out` option.
 
 Supported platforms
@@ -37,8 +37,8 @@
 Although *users* of this project are only expected to have Visual
 Studio 2012 or later, *developers* of the library are required to
 have Visual Studio 2017 or later, as the library uses C# 6 features
-in its implementation, as well as the new Visual Studio 2017 csproj 
-format. These features have no impact when using the compiled code - 
+in its implementation, as well as the new Visual Studio 2017 csproj
+format. These features have no impact when using the compiled code -
 they're only relevant when building the `Google.Protobuf` assembly.
 
 In order to run and debug the AddressBook example in the IDE, you must
@@ -56,19 +56,19 @@
 .NET 3.5
 ========
 
-We don't officially support .NET 3.5. However, there has been some effort 
-to make enabling .NET 3.5 support relatively painless in case you require it. 
-There's no guarantee that this will continue in the future, so rely on .NET 
+We don't officially support .NET 3.5. However, there has been some effort
+to make enabling .NET 3.5 support relatively painless in case you require it.
+There's no guarantee that this will continue in the future, so rely on .NET
 3.5 support at your peril.
 
-To enable .NET 3.5 support, you must edit the `TargetFrameworks` elements of 
-[src/Google.Protobuf/Google.Protobuf.csproj](src/Google.Protobuf/Google.Protobuf.csproj) 
-(and [src/Google.Protobuf.Test/Google.Protobuf.Test.csproj](src/Google.Protobuf.Test/Google.Protobuf.Test.csproj) 
-if you want to run the unit tests): 
+To enable .NET 3.5 support, you must edit the `TargetFrameworks` elements of
+[src/Google.Protobuf/Google.Protobuf.csproj](src/Google.Protobuf/Google.Protobuf.csproj)
+(and [src/Google.Protobuf.Test/Google.Protobuf.Test.csproj](src/Google.Protobuf.Test/Google.Protobuf.Test.csproj)
+if you want to run the unit tests):
 
-Open the .csproj file in a text editor and simply add `net35` to the list of 
-target frameworks, noting that the `TargetFrameworks` element appears twice in 
-the file (once in the first `PropertyGroup` element, and again in the second 
+Open the .csproj file in a text editor and simply add `net35` to the list of
+target frameworks, noting that the `TargetFrameworks` element appears twice in
+the file (once in the first `PropertyGroup` element, and again in the second
 `PropertyGroup` element, i.e., the one with the conditional).
 
 History of C# protobufs
diff --git a/csharp/compatibility_tests/v3.0.0/protos/csharp/protos/unittest_issues.proto b/csharp/compatibility_tests/v3.0.0/protos/csharp/protos/unittest_issues.proto
index 7bec1f8..b6178bf 100644
--- a/csharp/compatibility_tests/v3.0.0/protos/csharp/protos/unittest_issues.proto
+++ b/csharp/compatibility_tests/v3.0.0/protos/csharp/protos/unittest_issues.proto
@@ -20,7 +20,7 @@
 
 // Old issue 13: http://code.google.com/p/protobuf-csharp-port/issues/detail?id=13
 // New issue 309: https://github.com/protocolbuffers/protobuf/issues/309
- 
+
 // message A {
 //    optional int32 _A = 1;
 // }
@@ -101,21 +101,21 @@
   // that will require fixing other tests in multiple platforms.
   // Alternatively, consider just adding this to
   // unittest_proto3.proto if multiple platforms want it.
-  
+
   int32 plain_int32 = 4;
 
   oneof o1 {
     string o1_string = 2;
     int32 o1_int32 = 5;
   }
-  
+
   string plain_string = 1;
-  
+
   oneof o2 {
     int32 o2_int32 = 6;
     string o2_string = 3;
   }
-  
+
 }
 
 message TestJsonName {
diff --git a/csharp/compatibility_tests/v3.0.0/src/Google.Protobuf.Test/Collections/MapFieldTest.cs b/csharp/compatibility_tests/v3.0.0/src/Google.Protobuf.Test/Collections/MapFieldTest.cs
index 9c84590..3b4e1d3 100644
--- a/csharp/compatibility_tests/v3.0.0/src/Google.Protobuf.Test/Collections/MapFieldTest.cs
+++ b/csharp/compatibility_tests/v3.0.0/src/Google.Protobuf.Test/Collections/MapFieldTest.cs
@@ -86,7 +86,7 @@
             var map = new MapField<string, ForeignMessage>();
             Assert.Throws<ArgumentNullException>(() => map[null] = new ForeignMessage());
         }
-        
+
         [Test]
         public void AddPreservesInsertionOrder()
         {
@@ -471,7 +471,7 @@
             keys.CopyTo(array, 1);
             CollectionAssert.AreEqual(new[] { null, "foo", "x", null }, array);
         }
-        
+
         // Just test keys - we know the implementation is the same for values
         [Test]
         public void NonGenericViewCopyTo()
diff --git a/csharp/compatibility_tests/v3.0.0/src/Google.Protobuf.Test/Compatibility/TypeExtensionsTest.cs b/csharp/compatibility_tests/v3.0.0/src/Google.Protobuf.Test/Compatibility/TypeExtensionsTest.cs
index f430b06..e8a3d36 100644
--- a/csharp/compatibility_tests/v3.0.0/src/Google.Protobuf.Test/Compatibility/TypeExtensionsTest.cs
+++ b/csharp/compatibility_tests/v3.0.0/src/Google.Protobuf.Test/Compatibility/TypeExtensionsTest.cs
@@ -59,7 +59,7 @@
         [TestCase(typeof(string), typeof(int), false)]
         [TestCase(typeof(int), typeof(int), true)]
         [TestCase(typeof(ValueType), typeof(int), true)]
-        [TestCase(typeof(long), typeof(int), false)] // 
+        [TestCase(typeof(long), typeof(int), false)] //
         public void IsAssignableFrom(Type target, Type argument, bool expected)
         {
             Assert.AreEqual(expected, TypeExtensions.IsAssignableFrom(target, argument));
diff --git a/csharp/compatibility_tests/v3.0.0/src/Google.Protobuf.Test/Google.Protobuf.Test.csproj b/csharp/compatibility_tests/v3.0.0/src/Google.Protobuf.Test/Google.Protobuf.Test.csproj
index 06d07b9..6bc1e0c 100644
--- a/csharp/compatibility_tests/v3.0.0/src/Google.Protobuf.Test/Google.Protobuf.Test.csproj
+++ b/csharp/compatibility_tests/v3.0.0/src/Google.Protobuf.Test/Google.Protobuf.Test.csproj
@@ -18,7 +18,7 @@
     <PackageReference Include="NUnitLite" Version="3.6.1" />
   </ItemGroup>
 
-  <!-- 
+  <!--
     - Override target frameworks on non-Windows to just .NET Core
     - Doing this conditionally in the initial PropertyGroup confuses
     - Visual Studio.
@@ -26,5 +26,5 @@
   <PropertyGroup Condition="'$(OS)' != 'Windows_NT'">
     <TargetFrameworks>netcoreapp1.0</TargetFrameworks>
   </PropertyGroup>
-  
+
 </Project>
diff --git a/csharp/compatibility_tests/v3.0.0/src/Google.Protobuf.Test/JsonTokenizerTest.cs b/csharp/compatibility_tests/v3.0.0/src/Google.Protobuf.Test/JsonTokenizerTest.cs
index 527ab33..2e690c1 100644
--- a/csharp/compatibility_tests/v3.0.0/src/Google.Protobuf.Test/JsonTokenizerTest.cs
+++ b/csharp/compatibility_tests/v3.0.0/src/Google.Protobuf.Test/JsonTokenizerTest.cs
@@ -240,7 +240,7 @@
             AssertTokens("{'x': 'y'}",
                 JsonToken.StartObject, JsonToken.Name("x"), JsonToken.Value("y"), JsonToken.EndObject);
         }
-        
+
         [Test]
         [TestCase("[10, 20", 3)]
         [TestCase("[10,", 2)]
@@ -305,7 +305,7 @@
         [Test]
         public void ObjectMixedType()
         {
-            AssertTokens(@"{'a': 1, 'b': 'bar', 'c': null, 'd': false, 'e': true, 
+            AssertTokens(@"{'a': 1, 'b': 'bar', 'c': null, 'd': false, 'e': true,
                            'f': [2], 'g': {'x':'y' }}",
                 JsonToken.StartObject,
                 JsonToken.Name("a"),
@@ -349,12 +349,12 @@
             Assert.AreEqual(JsonToken.EndDocument, tokenizer.Next());
             Assert.Throws<InvalidOperationException>(() => tokenizer.Next());
         }
-       
+
         /// <summary>
         /// Asserts that the specified JSON is tokenized into the given sequence of tokens.
         /// All apostrophes are first converted to double quotes, allowing any tests
         /// that don't need to check actual apostrophe handling to use apostrophes in the JSON, avoiding
-        /// messy string literal escaping. The "end document" token is not specified in the list of 
+        /// messy string literal escaping. The "end document" token is not specified in the list of
         /// expected tokens, but is implicit.
         /// </summary>
         private static void AssertTokens(string json, params JsonToken[] expectedTokens)
@@ -366,7 +366,7 @@
         /// Asserts that the specified JSON is tokenized into the given sequence of tokens.
         /// Unlike <see cref="AssertTokens(string, JsonToken[])"/>, this does not perform any character
         /// replacement on the specified JSON, and should be used when the text contains apostrophes which
-        /// are expected to be used *as* apostrophes. The "end document" token is not specified in the list of 
+        /// are expected to be used *as* apostrophes. The "end document" token is not specified in the list of
         /// expected tokens, but is implicit.
         /// </summary>
         private static void AssertTokensNoReplacement(string json, params JsonToken[] expectedTokens)
diff --git a/csharp/compatibility_tests/v3.0.0/src/Google.Protobuf.Test/Reflection/DescriptorsTest.cs b/csharp/compatibility_tests/v3.0.0/src/Google.Protobuf.Test/Reflection/DescriptorsTest.cs
index 52d5a67..0520ada 100644
--- a/csharp/compatibility_tests/v3.0.0/src/Google.Protobuf.Test/Reflection/DescriptorsTest.cs
+++ b/csharp/compatibility_tests/v3.0.0/src/Google.Protobuf.Test/Reflection/DescriptorsTest.cs
@@ -150,7 +150,7 @@
             Assert.AreEqual(UnittestProto3Reflection.Descriptor, primitiveField.File);
             Assert.AreEqual(FieldType.Int32, primitiveField.FieldType);
             Assert.IsNull(primitiveField.Proto.Options);
-            
+
             Assert.AreEqual("single_nested_enum", enumField.Name);
             Assert.AreEqual(FieldType.Enum, enumField.FieldType);
             // Assert.AreEqual(TestAllTypes.Types.NestedEnum.DescriptorProtoFile, enumField.EnumType);
@@ -242,7 +242,7 @@
         // NestedMessage single_nested_message = 200;
         [Test]
         public void FieldListOrderings()
-        { 
+        {
             var fields = TestFieldOrderings.Descriptor.Fields;
             Assert.AreEqual(new[] { 11, 1, 101, 200 }, fields.InDeclarationOrder().Select(x => x.FieldNumber));
             Assert.AreEqual(new[] { 1, 11, 101, 200 }, fields.InFieldNumberOrder().Select(x => x.FieldNumber));
diff --git a/csharp/compatibility_tests/v3.0.0/src/Google.Protobuf.Test/Reflection/FieldAccessTest.cs b/csharp/compatibility_tests/v3.0.0/src/Google.Protobuf.Test/Reflection/FieldAccessTest.cs
index a488af3..46cb1af 100644
--- a/csharp/compatibility_tests/v3.0.0/src/Google.Protobuf.Test/Reflection/FieldAccessTest.cs
+++ b/csharp/compatibility_tests/v3.0.0/src/Google.Protobuf.Test/Reflection/FieldAccessTest.cs
@@ -213,6 +213,6 @@
             var descriptor = TestAllTypes.Descriptor;
             Assert.Throws<KeyNotFoundException>(() => descriptor.Fields[999999].ToString());
             Assert.Throws<KeyNotFoundException>(() => descriptor.Fields["not found"].ToString());
-        }        
+        }
     }
 }
diff --git a/csharp/compatibility_tests/v3.0.0/src/Google.Protobuf.Test/SampleEnum.cs b/csharp/compatibility_tests/v3.0.0/src/Google.Protobuf.Test/SampleEnum.cs
index 77447af..44f232a 100644
--- a/csharp/compatibility_tests/v3.0.0/src/Google.Protobuf.Test/SampleEnum.cs
+++ b/csharp/compatibility_tests/v3.0.0/src/Google.Protobuf.Test/SampleEnum.cs
@@ -29,7 +29,7 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #endregion
-    
+
 namespace Google.Protobuf
 {
     // Just a sample enum with positive and negative values to be used in tests.
diff --git a/csharp/compatibility_tests/v3.0.0/src/Google.Protobuf.Test/WellKnownTypes/TimestampTest.cs b/csharp/compatibility_tests/v3.0.0/src/Google.Protobuf.Test/WellKnownTypes/TimestampTest.cs
index 9ecd24c..548c585 100644
--- a/csharp/compatibility_tests/v3.0.0/src/Google.Protobuf.Test/WellKnownTypes/TimestampTest.cs
+++ b/csharp/compatibility_tests/v3.0.0/src/Google.Protobuf.Test/WellKnownTypes/TimestampTest.cs
@@ -99,7 +99,7 @@
             Duration difference = new Duration { Seconds = 1999, Nanos = Duration.NanosecondsPerSecond - 5000 };
             Assert.AreEqual(difference, t1 - t2);
             Assert.AreEqual(-difference, t2 - t1);
-            
+
             Assert.AreEqual(t1, t2 + difference);
             Assert.AreEqual(t2, t1 - difference);
         }
diff --git a/csharp/compatibility_tests/v3.0.0/src/Google.Protobuf.Test/WellKnownTypes/WrappersTest.cs b/csharp/compatibility_tests/v3.0.0/src/Google.Protobuf.Test/WellKnownTypes/WrappersTest.cs
index 5b7185d..0df4ac4 100644
--- a/csharp/compatibility_tests/v3.0.0/src/Google.Protobuf.Test/WellKnownTypes/WrappersTest.cs
+++ b/csharp/compatibility_tests/v3.0.0/src/Google.Protobuf.Test/WellKnownTypes/WrappersTest.cs
@@ -135,7 +135,7 @@
                 DoubleField = { 12.5, -1.5, 0d },
                 FloatField = { 123.25f, -20f, 0f },
                 Int32Field = { int.MaxValue, int.MinValue, 0 },
-                Int64Field = { long.MaxValue, long.MinValue, 0L },                
+                Int64Field = { long.MaxValue, long.MinValue, 0L },
                 StringField = { "First", "Second", "" },
                 Uint32Field = { uint.MaxValue, uint.MinValue, 0U },
                 Uint64Field = { ulong.MaxValue, ulong.MinValue, 0UL },
@@ -403,7 +403,7 @@
 
             output.Flush();
             stream.Position = 0;
-            
+
             var message = TestWellKnownTypes.Parser.ParseFrom(stream);
             Assert.AreEqual(6, message.Int32Field);
         }
diff --git a/csharp/protos/unittest_issues.proto b/csharp/protos/unittest_issues.proto
index 1619f13..b4a88d8 100644
--- a/csharp/protos/unittest_issues.proto
+++ b/csharp/protos/unittest_issues.proto
@@ -19,7 +19,7 @@
 
 // Old issue 13: http://code.google.com/p/protobuf-csharp-port/issues/detail?id=13
 // New issue 309: https://github.com/protocolbuffers/protobuf/issues/309
- 
+
 // message A {
 //    optional int32 _A = 1;
 // }
@@ -100,21 +100,21 @@
   // that will require fixing other tests in multiple platforms.
   // Alternatively, consider just adding this to
   // unittest_proto3.proto if multiple platforms want it.
-  
+
   int32 plain_int32 = 4;
 
   oneof o1 {
     string o1_string = 2;
     int32 o1_int32 = 5;
   }
-  
+
   string plain_string = 1;
-  
+
   oneof o2 {
     int32 o2_int32 = 6;
     string o2_string = 3;
   }
-  
+
 }
 
 message TestJsonName {
diff --git a/csharp/protos/unittest_proto3.proto b/csharp/protos/unittest_proto3.proto
index bf88f6b..884beae 100644
--- a/csharp/protos/unittest_proto3.proto
+++ b/csharp/protos/unittest_proto3.proto
@@ -392,13 +392,13 @@
     // Leading nested message field comment
     string nested_text = 1;
   }
-  
+
   // Leading nested enum comment
   enum NestedCommentEnum {
     // Zero value comment
     ZERO_VALUE = 0;
   }
-  
+
   // Leading field comment
   string text = 1; // Trailing field comment
 }
diff --git a/csharp/src/AddressBook/Addressbook.cs b/csharp/src/AddressBook/Addressbook.cs
index c05125c..d3e1ea9 100644
--- a/csharp/src/AddressBook/Addressbook.cs
+++ b/csharp/src/AddressBook/Addressbook.cs
@@ -260,9 +260,7 @@
       while ((tag = input.ReadTag()) != 0) {
         switch(tag) {
           default:
-            if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
-              return;
-            }
+            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
             break;
           case 10: {
             Name = input.ReadString();
@@ -442,9 +440,7 @@
           while ((tag = input.ReadTag()) != 0) {
             switch(tag) {
               default:
-                if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
-                  return;
-                }
+                _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
                 break;
               case 10: {
                 Number = input.ReadString();
@@ -577,9 +573,7 @@
       while ((tag = input.ReadTag()) != 0) {
         switch(tag) {
           default:
-            if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
-              return;
-            }
+            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
             break;
           case 10: {
             people_.AddEntriesFrom(input, _repeated_people_codec);
diff --git a/csharp/src/Google.Protobuf.Conformance/Conformance.cs b/csharp/src/Google.Protobuf.Conformance/Conformance.cs
index 73a140d..0a51062 100644
--- a/csharp/src/Google.Protobuf.Conformance/Conformance.cs
+++ b/csharp/src/Google.Protobuf.Conformance/Conformance.cs
@@ -216,9 +216,7 @@
       while ((tag = input.ReadTag()) != 0) {
         switch(tag) {
           default:
-            if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
-              return;
-            }
+            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
             break;
           case 10: {
             failure_.AddEntriesFrom(input, _repeated_failure_codec);
@@ -581,9 +579,7 @@
       while ((tag = input.ReadTag()) != 0) {
         switch(tag) {
           default:
-            if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
-              return;
-            }
+            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
             break;
           case 10: {
             ProtobufPayload = input.ReadBytes();
@@ -1001,9 +997,7 @@
       while ((tag = input.ReadTag()) != 0) {
         switch(tag) {
           default:
-            if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
-              return;
-            }
+            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
             break;
           case 10: {
             ParseError = input.ReadString();
@@ -1166,9 +1160,7 @@
       while ((tag = input.ReadTag()) != 0) {
         switch(tag) {
           default:
-            if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
-              return;
-            }
+            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
             break;
           case 8: {
             UseJspbArrayAnyFormat = input.ReadBool();
diff --git a/csharp/src/Google.Protobuf.Conformance/Program.cs b/csharp/src/Google.Protobuf.Conformance/Program.cs
index 1eac00b..0d281e4 100644
--- a/csharp/src/Google.Protobuf.Conformance/Program.cs
+++ b/csharp/src/Google.Protobuf.Conformance/Program.cs
@@ -93,17 +93,17 @@
                         var parser = new JsonParser(new JsonParser.Settings(20, typeRegistry));
                         message = parser.Parse<ProtobufTestMessages.Proto3.TestAllTypesProto3>(request.JsonPayload);
                         break;
-                    case ConformanceRequest.PayloadOneofCase.ProtobufPayload: 
+                    case ConformanceRequest.PayloadOneofCase.ProtobufPayload:
                     {
                         if (request.MessageType.Equals("protobuf_test_messages.proto3.TestAllTypesProto3"))
                         {
                             message = ProtobufTestMessages.Proto3.TestAllTypesProto3.Parser.ParseFrom(request.ProtobufPayload);
-                        }							
-                        else if (request.MessageType.Equals("protobuf_test_messages.proto2.TestAllTypesProto2")) 
+                        }
+                        else if (request.MessageType.Equals("protobuf_test_messages.proto2.TestAllTypesProto2"))
                         {
                             return new ConformanceResponse { Skipped = "CSharp doesn't support proto2" };
                         }
-                        else 
+                        else
                         {
                             throw new Exception(" Protobuf request doesn't have specific payload type");
                         }
diff --git a/csharp/src/Google.Protobuf.Test/Collections/MapFieldTest.cs b/csharp/src/Google.Protobuf.Test/Collections/MapFieldTest.cs
index 8791dff..f64ebac 100644
--- a/csharp/src/Google.Protobuf.Test/Collections/MapFieldTest.cs
+++ b/csharp/src/Google.Protobuf.Test/Collections/MapFieldTest.cs
@@ -86,7 +86,7 @@
             var map = new MapField<string, ForeignMessage>();
             Assert.Throws<ArgumentNullException>(() => map[null] = new ForeignMessage());
         }
-        
+
         [Test]
         public void AddPreservesInsertionOrder()
         {
@@ -471,7 +471,7 @@
             keys.CopyTo(array, 1);
             CollectionAssert.AreEqual(new[] { null, "foo", "x", null }, array);
         }
-        
+
         // Just test keys - we know the implementation is the same for values
         [Test]
         public void NonGenericViewCopyTo()
diff --git a/csharp/src/Google.Protobuf.Test/Collections/ProtobufEqualityComparersTest.cs b/csharp/src/Google.Protobuf.Test/Collections/ProtobufEqualityComparersTest.cs
index c76d7ca..594a879 100644
--- a/csharp/src/Google.Protobuf.Test/Collections/ProtobufEqualityComparersTest.cs
+++ b/csharp/src/Google.Protobuf.Test/Collections/ProtobufEqualityComparersTest.cs
@@ -120,5 +120,5 @@
                 }
             }
         }
-    }    
+    }
 }
diff --git a/csharp/src/Google.Protobuf.Test/Compatibility/TypeExtensionsTest.cs b/csharp/src/Google.Protobuf.Test/Compatibility/TypeExtensionsTest.cs
index abbe3c9..5d86c20 100644
--- a/csharp/src/Google.Protobuf.Test/Compatibility/TypeExtensionsTest.cs
+++ b/csharp/src/Google.Protobuf.Test/Compatibility/TypeExtensionsTest.cs
@@ -59,7 +59,7 @@
         [TestCase(typeof(string), typeof(int), false)]
         [TestCase(typeof(int), typeof(int), true)]
         [TestCase(typeof(ValueType), typeof(int), true)]
-        [TestCase(typeof(long), typeof(int), false)] // 
+        [TestCase(typeof(long), typeof(int), false)] //
         public void IsAssignableFrom(Type target, Type argument, bool expected)
         {
             Assert.AreEqual(expected, TypeExtensions.IsAssignableFrom(target, argument));
diff --git a/csharp/src/Google.Protobuf.Test/FieldMaskTreeTest.cs b/csharp/src/Google.Protobuf.Test/FieldMaskTreeTest.cs
index b0caab9..f71744a 100644
--- a/csharp/src/Google.Protobuf.Test/FieldMaskTreeTest.cs
+++ b/csharp/src/Google.Protobuf.Test/FieldMaskTreeTest.cs
@@ -68,7 +68,7 @@
             paths = tree.ToFieldMask().Paths;
             Assert.AreEqual(3, paths.Count);
             Assert.Contains("bar.baz", paths);
-            
+
             // Redundant sub-path.
             tree.AddFieldPath("foo.bar");
             paths = tree.ToFieldMask().Paths;
@@ -79,7 +79,7 @@
             paths = tree.ToFieldMask().Paths;
             Assert.AreEqual(4, paths.Count);
             Assert.Contains("bar.quz", paths);
-            
+
             // A path that matches several existing sub-paths.
             tree.AddFieldPath("bar");
             paths = tree.ToFieldMask().Paths;
diff --git a/csharp/src/Google.Protobuf.Test/Google.Protobuf.Test.csproj b/csharp/src/Google.Protobuf.Test/Google.Protobuf.Test.csproj
index f286e0a..11adb11 100644
--- a/csharp/src/Google.Protobuf.Test/Google.Protobuf.Test.csproj
+++ b/csharp/src/Google.Protobuf.Test/Google.Protobuf.Test.csproj
@@ -18,7 +18,7 @@
     <PackageReference Include="NUnit3TestAdapter" Version="3.9.0" />
   </ItemGroup>
 
-  <!-- 
+  <!--
     - Override target frameworks on non-Windows to just .NET Core
     - Doing this conditionally in the initial PropertyGroup confuses
     - Visual Studio.
diff --git a/csharp/src/Google.Protobuf.Test/JsonFormatterTest.cs b/csharp/src/Google.Protobuf.Test/JsonFormatterTest.cs
index 1c7a8cd..b07a841 100644
--- a/csharp/src/Google.Protobuf.Test/JsonFormatterTest.cs
+++ b/csharp/src/Google.Protobuf.Test/JsonFormatterTest.cs
@@ -243,7 +243,7 @@
         [Test]
         public void InvalidSurrogatePairsFail()
         {
-            // Note: don't use TestCase for these, as the strings can't be reliably represented 
+            // Note: don't use TestCase for these, as the strings can't be reliably represented
             // See http://codeblog.jonskeet.uk/2014/11/07/when-is-a-string-not-a-string/
 
             // Lone low surrogate
diff --git a/csharp/src/Google.Protobuf.Test/JsonTokenizerTest.cs b/csharp/src/Google.Protobuf.Test/JsonTokenizerTest.cs
index 33d3503..df43eff 100644
--- a/csharp/src/Google.Protobuf.Test/JsonTokenizerTest.cs
+++ b/csharp/src/Google.Protobuf.Test/JsonTokenizerTest.cs
@@ -240,7 +240,7 @@
             AssertTokens("{'x': 'y'}",
                 JsonToken.StartObject, JsonToken.Name("x"), JsonToken.Value("y"), JsonToken.EndObject);
         }
-        
+
         [Test]
         [TestCase("[10, 20", 3)]
         [TestCase("[10,", 2)]
@@ -305,7 +305,7 @@
         [Test]
         public void ObjectMixedType()
         {
-            AssertTokens(@"{'a': 1, 'b': 'bar', 'c': null, 'd': false, 'e': true, 
+            AssertTokens(@"{'a': 1, 'b': 'bar', 'c': null, 'd': false, 'e': true,
                            'f': [2], 'g': {'x':'y' }}",
                 JsonToken.StartObject,
                 JsonToken.Name("a"),
@@ -365,12 +365,12 @@
             tokenizer.SkipValue();
             Assert.AreEqual("next", tokenizer.Next().StringValue);
         }
-       
+
         /// <summary>
         /// Asserts that the specified JSON is tokenized into the given sequence of tokens.
         /// All apostrophes are first converted to double quotes, allowing any tests
         /// that don't need to check actual apostrophe handling to use apostrophes in the JSON, avoiding
-        /// messy string literal escaping. The "end document" token is not specified in the list of 
+        /// messy string literal escaping. The "end document" token is not specified in the list of
         /// expected tokens, but is implicit.
         /// </summary>
         private static void AssertTokens(string json, params JsonToken[] expectedTokens)
@@ -382,7 +382,7 @@
         /// Asserts that the specified JSON is tokenized into the given sequence of tokens.
         /// Unlike <see cref="AssertTokens(string, JsonToken[])"/>, this does not perform any character
         /// replacement on the specified JSON, and should be used when the text contains apostrophes which
-        /// are expected to be used *as* apostrophes. The "end document" token is not specified in the list of 
+        /// are expected to be used *as* apostrophes. The "end document" token is not specified in the list of
         /// expected tokens, but is implicit.
         /// </summary>
         private static void AssertTokensNoReplacement(string json, params JsonToken[] expectedTokens)
diff --git a/csharp/src/Google.Protobuf.Test/Reflection/DescriptorsTest.cs b/csharp/src/Google.Protobuf.Test/Reflection/DescriptorsTest.cs
index 8e1097a..264cbbe 100644
--- a/csharp/src/Google.Protobuf.Test/Reflection/DescriptorsTest.cs
+++ b/csharp/src/Google.Protobuf.Test/Reflection/DescriptorsTest.cs
@@ -256,7 +256,7 @@
             Assert.AreEqual(unitTestProto3Descriptor, primitiveField.File);
             Assert.AreEqual(FieldType.Int32, primitiveField.FieldType);
             Assert.IsNull(primitiveField.Proto.Options);
-            
+
             Assert.AreEqual("single_nested_enum", enumField.Name);
             Assert.AreEqual(FieldType.Enum, enumField.FieldType);
             Assert.AreEqual(testAllTypesDescriptor.EnumTypes[0], enumField.EnumType);
@@ -352,7 +352,7 @@
         // NestedMessage single_nested_message = 200;
         [Test]
         public void FieldListOrderings()
-        { 
+        {
             var fields = TestFieldOrderings.Descriptor.Fields;
             Assert.AreEqual(new[] { 11, 1, 101, 200 }, fields.InDeclarationOrder().Select(x => x.FieldNumber));
             Assert.AreEqual(new[] { 1, 11, 101, 200 }, fields.InFieldNumberOrder().Select(x => x.FieldNumber));
diff --git a/csharp/src/Google.Protobuf.Test/Reflection/FieldAccessTest.cs b/csharp/src/Google.Protobuf.Test/Reflection/FieldAccessTest.cs
index a488af3..46cb1af 100644
--- a/csharp/src/Google.Protobuf.Test/Reflection/FieldAccessTest.cs
+++ b/csharp/src/Google.Protobuf.Test/Reflection/FieldAccessTest.cs
@@ -213,6 +213,6 @@
             var descriptor = TestAllTypes.Descriptor;
             Assert.Throws<KeyNotFoundException>(() => descriptor.Fields[999999].ToString());
             Assert.Throws<KeyNotFoundException>(() => descriptor.Fields["not found"].ToString());
-        }        
+        }
     }
 }
diff --git a/csharp/src/Google.Protobuf.Test/SampleEnum.cs b/csharp/src/Google.Protobuf.Test/SampleEnum.cs
index 77447af..44f232a 100644
--- a/csharp/src/Google.Protobuf.Test/SampleEnum.cs
+++ b/csharp/src/Google.Protobuf.Test/SampleEnum.cs
@@ -29,7 +29,7 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #endregion
-    
+
 namespace Google.Protobuf
 {
     // Just a sample enum with positive and negative values to be used in tests.
diff --git a/csharp/src/Google.Protobuf.Test/SampleNaNs.cs b/csharp/src/Google.Protobuf.Test/SampleNaNs.cs
index 08b5019..34019ac 100644
--- a/csharp/src/Google.Protobuf.Test/SampleNaNs.cs
+++ b/csharp/src/Google.Protobuf.Test/SampleNaNs.cs
@@ -43,7 +43,7 @@
 
         // Signalling bit is inverted compared with double.NaN. Doesn't really matter
         // whether that makes it quiet or signalling - it's different.
-        public static double SignallingFlipped { get; } = 
+        public static double SignallingFlipped { get; } =
             BitConverter.Int64BitsToDouble(BitConverter.DoubleToInt64Bits(double.NaN) ^ -0x8000_0000_0000_0000L);
 
         // A bit in the middle of the mantissa is flipped; this difference is preserved when casting to float.
diff --git a/csharp/src/Google.Protobuf.Test/TestProtos/MapUnittestProto3.cs b/csharp/src/Google.Protobuf.Test/TestProtos/MapUnittestProto3.cs
index 2844ca6..6d3cd02 100644
--- a/csharp/src/Google.Protobuf.Test/TestProtos/MapUnittestProto3.cs
+++ b/csharp/src/Google.Protobuf.Test/TestProtos/MapUnittestProto3.cs
@@ -541,9 +541,7 @@
       while ((tag = input.ReadTag()) != 0) {
         switch(tag) {
           default:
-            if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
-              return;
-            }
+            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
             break;
           case 10: {
             mapInt32Int32_.AddEntriesFrom(input, _map_mapInt32Int32_codec);
@@ -739,9 +737,7 @@
       while ((tag = input.ReadTag()) != 0) {
         switch(tag) {
           default:
-            if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
-              return;
-            }
+            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
             break;
           case 10: {
             if (testMap_ == null) {
@@ -865,9 +861,7 @@
       while ((tag = input.ReadTag()) != 0) {
         switch(tag) {
           default:
-            if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
-              return;
-            }
+            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
             break;
           case 10: {
             mapInt32Message_.AddEntriesFrom(input, _map_mapInt32Message_codec);
@@ -1007,9 +1001,7 @@
       while ((tag = input.ReadTag()) != 0) {
         switch(tag) {
           default:
-            if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
-              return;
-            }
+            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
             break;
           case 10: {
             map1_.AddEntriesFrom(input, _map_map1_codec);
@@ -1358,9 +1350,7 @@
       while ((tag = input.ReadTag()) != 0) {
         switch(tag) {
           default:
-            if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
-              return;
-            }
+            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
             break;
           case 10: {
             mapInt32Int32_.AddEntriesFrom(input, _map_mapInt32Int32_codec);
@@ -1541,9 +1531,7 @@
       while ((tag = input.ReadTag()) != 0) {
         switch(tag) {
           default:
-            if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
-              return;
-            }
+            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
             break;
           case 10: {
             type_.AddEntriesFrom(input, _map_type_codec);
@@ -1678,9 +1666,7 @@
       while ((tag = input.ReadTag()) != 0) {
         switch(tag) {
           default:
-            if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
-              return;
-            }
+            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
             break;
           case 10: {
             entry_.AddEntriesFrom(input, _map_entry_codec);
diff --git a/csharp/src/Google.Protobuf.Test/TestProtos/TestMessagesProto3.cs b/csharp/src/Google.Protobuf.Test/TestProtos/TestMessagesProto3.cs
index b59075b..b14ee6c 100644
--- a/csharp/src/Google.Protobuf.Test/TestProtos/TestMessagesProto3.cs
+++ b/csharp/src/Google.Protobuf.Test/TestProtos/TestMessagesProto3.cs
@@ -2895,9 +2895,7 @@
       while ((tag = input.ReadTag()) != 0) {
         switch(tag) {
           default:
-            if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
-              return;
-            }
+            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
             break;
           case 8: {
             OptionalInt32 = input.ReadInt32();
@@ -3625,9 +3623,7 @@
           while ((tag = input.ReadTag()) != 0) {
             switch(tag) {
               default:
-                if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
-                  return;
-                }
+                _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
                 break;
               case 8: {
                 A = input.ReadInt32();
@@ -3768,9 +3764,7 @@
       while ((tag = input.ReadTag()) != 0) {
         switch(tag) {
           default:
-            if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
-              return;
-            }
+            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
             break;
           case 8: {
             C = input.ReadInt32();
diff --git a/csharp/src/Google.Protobuf.Test/TestProtos/UnittestCustomOptionsProto3.cs b/csharp/src/Google.Protobuf.Test/TestProtos/UnittestCustomOptionsProto3.cs
index 9b9ffe2..2a9efe5 100644
--- a/csharp/src/Google.Protobuf.Test/TestProtos/UnittestCustomOptionsProto3.cs
+++ b/csharp/src/Google.Protobuf.Test/TestProtos/UnittestCustomOptionsProto3.cs
@@ -352,9 +352,7 @@
       while ((tag = input.ReadTag()) != 0) {
         switch(tag) {
           default:
-            if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
-              return;
-            }
+            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
             break;
           case 10: {
             Field1 = input.ReadString();
@@ -480,9 +478,7 @@
       while ((tag = input.ReadTag()) != 0) {
         switch(tag) {
           default:
-            if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
-              return;
-            }
+            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
             break;
         }
       }
@@ -583,9 +579,7 @@
       while ((tag = input.ReadTag()) != 0) {
         switch(tag) {
           default:
-            if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
-              return;
-            }
+            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
             break;
         }
       }
@@ -686,9 +680,7 @@
       while ((tag = input.ReadTag()) != 0) {
         switch(tag) {
           default:
-            if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
-              return;
-            }
+            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
             break;
         }
       }
@@ -789,9 +781,7 @@
       while ((tag = input.ReadTag()) != 0) {
         switch(tag) {
           default:
-            if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
-              return;
-            }
+            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
             break;
         }
       }
@@ -892,9 +882,7 @@
       while ((tag = input.ReadTag()) != 0) {
         switch(tag) {
           default:
-            if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
-              return;
-            }
+            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
             break;
         }
       }
@@ -1008,9 +996,7 @@
       while ((tag = input.ReadTag()) != 0) {
         switch(tag) {
           default:
-            if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
-              return;
-            }
+            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
             break;
         }
       }
@@ -1111,9 +1097,7 @@
       while ((tag = input.ReadTag()) != 0) {
         switch(tag) {
           default:
-            if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
-              return;
-            }
+            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
             break;
         }
       }
@@ -1214,9 +1198,7 @@
       while ((tag = input.ReadTag()) != 0) {
         switch(tag) {
           default:
-            if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
-              return;
-            }
+            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
             break;
         }
       }
@@ -1317,9 +1299,7 @@
       while ((tag = input.ReadTag()) != 0) {
         switch(tag) {
           default:
-            if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
-              return;
-            }
+            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
             break;
         }
       }
@@ -1420,9 +1400,7 @@
       while ((tag = input.ReadTag()) != 0) {
         switch(tag) {
           default:
-            if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
-              return;
-            }
+            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
             break;
         }
       }
@@ -1523,9 +1501,7 @@
       while ((tag = input.ReadTag()) != 0) {
         switch(tag) {
           default:
-            if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
-              return;
-            }
+            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
             break;
         }
       }
@@ -1714,9 +1690,7 @@
       while ((tag = input.ReadTag()) != 0) {
         switch(tag) {
           default:
-            if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
-              return;
-            }
+            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
             break;
           case 8: {
             Foo = input.ReadInt32();
@@ -1928,9 +1902,7 @@
       while ((tag = input.ReadTag()) != 0) {
         switch(tag) {
           default:
-            if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
-              return;
-            }
+            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
             break;
           case 10: {
             if (bar_ == null) {
@@ -2079,9 +2051,7 @@
           while ((tag = input.ReadTag()) != 0) {
             switch(tag) {
               default:
-                if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
-                  return;
-                }
+                _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
                 break;
               case 8: {
                 Waldo = input.ReadInt32();
@@ -2215,9 +2185,7 @@
       while ((tag = input.ReadTag()) != 0) {
         switch(tag) {
           default:
-            if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
-              return;
-            }
+            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
             break;
           case 8: {
             Qux = input.ReadInt32();
@@ -2325,9 +2293,7 @@
       while ((tag = input.ReadTag()) != 0) {
         switch(tag) {
           default:
-            if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
-              return;
-            }
+            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
             break;
         }
       }
@@ -2509,9 +2475,7 @@
       while ((tag = input.ReadTag()) != 0) {
         switch(tag) {
           default:
-            if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
-              return;
-            }
+            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
             break;
           case 8: {
             I = input.ReadInt32();
@@ -2651,9 +2615,7 @@
       while ((tag = input.ReadTag()) != 0) {
         switch(tag) {
           default:
-            if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
-              return;
-            }
+            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
             break;
           case 8: {
             Fieldname = input.ReadInt32();
@@ -2761,9 +2723,7 @@
       while ((tag = input.ReadTag()) != 0) {
         switch(tag) {
           default:
-            if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
-              return;
-            }
+            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
             break;
         }
       }
@@ -2895,9 +2855,7 @@
           while ((tag = input.ReadTag()) != 0) {
             switch(tag) {
               default:
-                if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
-                  return;
-                }
+                _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
                 break;
               case 8: {
                 NestedField = input.ReadInt32();
diff --git a/csharp/src/Google.Protobuf.Test/TestProtos/UnittestImportProto3.cs b/csharp/src/Google.Protobuf.Test/TestProtos/UnittestImportProto3.cs
index 931dc2e..6bf9715 100644
--- a/csharp/src/Google.Protobuf.Test/TestProtos/UnittestImportProto3.cs
+++ b/csharp/src/Google.Protobuf.Test/TestProtos/UnittestImportProto3.cs
@@ -167,9 +167,7 @@
       while ((tag = input.ReadTag()) != 0) {
         switch(tag) {
           default:
-            if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
-              return;
-            }
+            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
             break;
           case 8: {
             D = input.ReadInt32();
diff --git a/csharp/src/Google.Protobuf.Test/TestProtos/UnittestImportPublicProto3.cs b/csharp/src/Google.Protobuf.Test/TestProtos/UnittestImportPublicProto3.cs
index fee0120..97d181a 100644
--- a/csharp/src/Google.Protobuf.Test/TestProtos/UnittestImportPublicProto3.cs
+++ b/csharp/src/Google.Protobuf.Test/TestProtos/UnittestImportPublicProto3.cs
@@ -155,9 +155,7 @@
       while ((tag = input.ReadTag()) != 0) {
         switch(tag) {
           default:
-            if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
-              return;
-            }
+            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
             break;
           case 8: {
             E = input.ReadInt32();
diff --git a/csharp/src/Google.Protobuf.Test/TestProtos/UnittestIssues.cs b/csharp/src/Google.Protobuf.Test/TestProtos/UnittestIssues.cs
index f8296b0..f27ab64 100644
--- a/csharp/src/Google.Protobuf.Test/TestProtos/UnittestIssues.cs
+++ b/csharp/src/Google.Protobuf.Test/TestProtos/UnittestIssues.cs
@@ -181,9 +181,7 @@
       while ((tag = input.ReadTag()) != 0) {
         switch(tag) {
           default:
-            if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
-              return;
-            }
+            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
             break;
         }
       }
@@ -286,9 +284,7 @@
           while ((tag = input.ReadTag()) != 0) {
             switch(tag) {
               default:
-                if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
-                  return;
-                }
+                _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
                 break;
             }
           }
@@ -391,9 +387,7 @@
               while ((tag = input.ReadTag()) != 0) {
                 switch(tag) {
                   default:
-                    if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
-                      return;
-                    }
+                    _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
                     break;
                 }
               }
@@ -560,9 +554,7 @@
       while ((tag = input.ReadTag()) != 0) {
         switch(tag) {
           default:
-            if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
-              return;
-            }
+            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
             break;
           case 8: {
             Value = (global::UnitTest.Issues.TestProtos.NegativeEnum) input.ReadEnum();
@@ -677,9 +669,7 @@
       while ((tag = input.ReadTag()) != 0) {
         switch(tag) {
           default:
-            if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
-              return;
-            }
+            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
             break;
         }
       }
@@ -909,9 +899,7 @@
       while ((tag = input.ReadTag()) != 0) {
         switch(tag) {
           default:
-            if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
-              return;
-            }
+            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
             break;
           case 8: {
             PrimitiveValue = input.ReadInt32();
@@ -1068,9 +1056,7 @@
       while ((tag = input.ReadTag()) != 0) {
         switch(tag) {
           default:
-            if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
-              return;
-            }
+            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
             break;
           case 8: {
             Item = input.ReadInt32();
@@ -1223,9 +1209,7 @@
       while ((tag = input.ReadTag()) != 0) {
         switch(tag) {
           default:
-            if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
-              return;
-            }
+            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
             break;
           case 8: {
             Types_ = input.ReadInt32();
@@ -1339,9 +1323,7 @@
           while ((tag = input.ReadTag()) != 0) {
             switch(tag) {
               default:
-                if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
-                  return;
-                }
+                _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
                 break;
             }
           }
@@ -1665,9 +1647,7 @@
       while ((tag = input.ReadTag()) != 0) {
         switch(tag) {
           default:
-            if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
-              return;
-            }
+            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
             break;
           case 10: {
             PlainString = input.ReadString();
@@ -1867,9 +1847,7 @@
       while ((tag = input.ReadTag()) != 0) {
         switch(tag) {
           default:
-            if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
-              return;
-            }
+            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
             break;
           case 10: {
             Name = input.ReadString();
@@ -2069,9 +2047,7 @@
       while ((tag = input.ReadTag()) != 0) {
         switch(tag) {
           default:
-            if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
-              return;
-            }
+            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
             break;
           case 10: {
             Text = input.ReadString();
@@ -2235,9 +2211,7 @@
           while ((tag = input.ReadTag()) != 0) {
             switch(tag) {
               default:
-                if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
-                  return;
-                }
+                _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
                 break;
               case 8: {
                 X = input.ReadInt32();
diff --git a/csharp/src/Google.Protobuf.Test/TestProtos/UnittestProto3.cs b/csharp/src/Google.Protobuf.Test/TestProtos/UnittestProto3.cs
index 1d4367b..bbbee22 100644
--- a/csharp/src/Google.Protobuf.Test/TestProtos/UnittestProto3.cs
+++ b/csharp/src/Google.Protobuf.Test/TestProtos/UnittestProto3.cs
@@ -1387,9 +1387,7 @@
       while ((tag = input.ReadTag()) != 0) {
         switch(tag) {
           default:
-            if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
-              return;
-            }
+            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
             break;
           case 8: {
             SingleInt32 = input.ReadInt32();
@@ -1757,9 +1755,7 @@
           while ((tag = input.ReadTag()) != 0) {
             switch(tag) {
               default:
-                if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
-                  return;
-                }
+                _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
                 break;
               case 8: {
                 Bb = input.ReadInt32();
@@ -1942,9 +1938,7 @@
       while ((tag = input.ReadTag()) != 0) {
         switch(tag) {
           default:
-            if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
-              return;
-            }
+            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
             break;
           case 10: {
             if (child_ == null) {
@@ -2088,9 +2082,7 @@
       while ((tag = input.ReadTag()) != 0) {
         switch(tag) {
           default:
-            if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
-              return;
-            }
+            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
             break;
           case 8: {
             DeprecatedInt32 = input.ReadInt32();
@@ -2223,9 +2215,7 @@
       while ((tag = input.ReadTag()) != 0) {
         switch(tag) {
           default:
-            if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
-              return;
-            }
+            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
             break;
           case 8: {
             C = input.ReadInt32();
@@ -2330,9 +2320,7 @@
       while ((tag = input.ReadTag()) != 0) {
         switch(tag) {
           default:
-            if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
-              return;
-            }
+            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
             break;
         }
       }
@@ -2463,9 +2451,7 @@
       while ((tag = input.ReadTag()) != 0) {
         switch(tag) {
           default:
-            if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
-              return;
-            }
+            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
             break;
           case 10: {
             if (foreignNested_ == null) {
@@ -2628,9 +2614,7 @@
       while ((tag = input.ReadTag()) != 0) {
         switch(tag) {
           default:
-            if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
-              return;
-            }
+            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
             break;
           case 8: {
             A = input.ReadInt32();
@@ -2790,9 +2774,7 @@
       while ((tag = input.ReadTag()) != 0) {
         switch(tag) {
           default:
-            if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
-              return;
-            }
+            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
             break;
           case 10: {
             if (a_ == null) {
@@ -2934,9 +2916,7 @@
       while ((tag = input.ReadTag()) != 0) {
         switch(tag) {
           default:
-            if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
-              return;
-            }
+            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
             break;
           case 10: {
             if (bb_ == null) {
@@ -3095,9 +3075,7 @@
       while ((tag = input.ReadTag()) != 0) {
         switch(tag) {
           default:
-            if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
-              return;
-            }
+            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
             break;
           case 10: {
             if (a_ == null) {
@@ -3233,9 +3211,7 @@
       while ((tag = input.ReadTag()) != 0) {
         switch(tag) {
           default:
-            if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
-              return;
-            }
+            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
             break;
           case 8: {
             Value = (global::Google.Protobuf.TestProtos.TestEnumWithDupValue) input.ReadEnum();
@@ -3507,9 +3483,7 @@
       while ((tag = input.ReadTag()) != 0) {
         switch(tag) {
           default:
-            if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
-              return;
-            }
+            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
             break;
           case 8: {
             PrimitiveField = input.ReadInt32();
@@ -3750,9 +3724,7 @@
       while ((tag = input.ReadTag()) != 0) {
         switch(tag) {
           default:
-            if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
-              return;
-            }
+            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
             break;
           case 8: {
             MyInt = input.ReadInt64();
@@ -3927,9 +3899,7 @@
           while ((tag = input.ReadTag()) != 0) {
             switch(tag) {
               default:
-                if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
-                  return;
-                }
+                _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
                 break;
               case 8: {
                 Bb = input.ReadInt32();
@@ -4067,9 +4037,7 @@
       while ((tag = input.ReadTag()) != 0) {
         switch(tag) {
           default:
-            if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
-              return;
-            }
+            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
             break;
           case 8: {
             SparseEnum = (global::Google.Protobuf.TestProtos.TestSparseEnum) input.ReadEnum();
@@ -4201,9 +4169,7 @@
       while ((tag = input.ReadTag()) != 0) {
         switch(tag) {
           default:
-            if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
-              return;
-            }
+            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
             break;
           case 10: {
             Data = input.ReadString();
@@ -4324,9 +4290,7 @@
       while ((tag = input.ReadTag()) != 0) {
         switch(tag) {
           default:
-            if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
-              return;
-            }
+            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
             break;
           case 10: {
             data_.AddEntriesFrom(input, _repeated_data_codec);
@@ -4455,9 +4419,7 @@
       while ((tag = input.ReadTag()) != 0) {
         switch(tag) {
           default:
-            if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
-              return;
-            }
+            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
             break;
           case 10: {
             Data = input.ReadBytes();
@@ -4586,9 +4548,7 @@
       while ((tag = input.ReadTag()) != 0) {
         switch(tag) {
           default:
-            if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
-              return;
-            }
+            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
             break;
           case 10: {
             Data = input.ReadBytes();
@@ -4720,9 +4680,7 @@
       while ((tag = input.ReadTag()) != 0) {
         switch(tag) {
           default:
-            if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
-              return;
-            }
+            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
             break;
           case 8: {
             Data = input.ReadInt32();
@@ -4851,9 +4809,7 @@
       while ((tag = input.ReadTag()) != 0) {
         switch(tag) {
           default:
-            if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
-              return;
-            }
+            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
             break;
           case 8: {
             Data = input.ReadUInt32();
@@ -4982,9 +4938,7 @@
       while ((tag = input.ReadTag()) != 0) {
         switch(tag) {
           default:
-            if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
-              return;
-            }
+            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
             break;
           case 8: {
             Data = input.ReadInt64();
@@ -5113,9 +5067,7 @@
       while ((tag = input.ReadTag()) != 0) {
         switch(tag) {
           default:
-            if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
-              return;
-            }
+            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
             break;
           case 8: {
             Data = input.ReadUInt64();
@@ -5244,9 +5196,7 @@
       while ((tag = input.ReadTag()) != 0) {
         switch(tag) {
           default:
-            if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
-              return;
-            }
+            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
             break;
           case 8: {
             Data = input.ReadBool();
@@ -5463,9 +5413,7 @@
       while ((tag = input.ReadTag()) != 0) {
         switch(tag) {
           default:
-            if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
-              return;
-            }
+            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
             break;
           case 8: {
             FooInt = input.ReadInt32();
@@ -5807,9 +5755,7 @@
       while ((tag = input.ReadTag()) != 0) {
         switch(tag) {
           default:
-            if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
-              return;
-            }
+            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
             break;
           case 722:
           case 720: {
@@ -6208,9 +6154,7 @@
       while ((tag = input.ReadTag()) != 0) {
         switch(tag) {
           default:
-            if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
-              return;
-            }
+            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
             break;
           case 722:
           case 720: {
@@ -6491,9 +6435,7 @@
       while ((tag = input.ReadTag()) != 0) {
         switch(tag) {
           default:
-            if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
-              return;
-            }
+            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
             break;
           case 98:
           case 101: {
@@ -6651,9 +6593,7 @@
       while ((tag = input.ReadTag()) != 0) {
         switch(tag) {
           default:
-            if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
-              return;
-            }
+            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
             break;
           case 10: {
             A = input.ReadString();
@@ -6761,9 +6701,7 @@
       while ((tag = input.ReadTag()) != 0) {
         switch(tag) {
           default:
-            if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
-              return;
-            }
+            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
             break;
         }
       }
@@ -6864,9 +6802,7 @@
       while ((tag = input.ReadTag()) != 0) {
         switch(tag) {
           default:
-            if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
-              return;
-            }
+            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
             break;
         }
       }
@@ -6967,9 +6903,7 @@
       while ((tag = input.ReadTag()) != 0) {
         switch(tag) {
           default:
-            if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
-              return;
-            }
+            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
             break;
         }
       }
@@ -7070,9 +7004,7 @@
       while ((tag = input.ReadTag()) != 0) {
         switch(tag) {
           default:
-            if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
-              return;
-            }
+            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
             break;
         }
       }
@@ -7173,9 +7105,7 @@
       while ((tag = input.ReadTag()) != 0) {
         switch(tag) {
           default:
-            if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
-              return;
-            }
+            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
             break;
         }
       }
@@ -7276,9 +7206,7 @@
       while ((tag = input.ReadTag()) != 0) {
         switch(tag) {
           default:
-            if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
-              return;
-            }
+            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
             break;
         }
       }
@@ -7379,9 +7307,7 @@
       while ((tag = input.ReadTag()) != 0) {
         switch(tag) {
           default:
-            if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
-              return;
-            }
+            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
             break;
         }
       }
@@ -7512,9 +7438,7 @@
       while ((tag = input.ReadTag()) != 0) {
         switch(tag) {
           default:
-            if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
-              return;
-            }
+            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
             break;
           case 10: {
             Text = input.ReadString();
@@ -7661,9 +7585,7 @@
           while ((tag = input.ReadTag()) != 0) {
             switch(tag) {
               default:
-                if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
-                  return;
-                }
+                _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
                 break;
               case 10: {
                 NestedText = input.ReadString();
diff --git a/csharp/src/Google.Protobuf.Test/TestProtos/UnittestWellKnownTypes.cs b/csharp/src/Google.Protobuf.Test/TestProtos/UnittestWellKnownTypes.cs
index a36825d..45f8ece 100644
--- a/csharp/src/Google.Protobuf.Test/TestProtos/UnittestWellKnownTypes.cs
+++ b/csharp/src/Google.Protobuf.Test/TestProtos/UnittestWellKnownTypes.cs
@@ -788,9 +788,7 @@
       while ((tag = input.ReadTag()) != 0) {
         switch(tag) {
           default:
-            if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
-              return;
-            }
+            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
             break;
           case 10: {
             if (anyField_ == null) {
@@ -1318,9 +1316,7 @@
       while ((tag = input.ReadTag()) != 0) {
         switch(tag) {
           default:
-            if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
-              return;
-            }
+            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
             break;
           case 10: {
             anyField_.AddEntriesFrom(input, _repeated_anyField_codec);
@@ -2031,9 +2027,7 @@
       while ((tag = input.ReadTag()) != 0) {
         switch(tag) {
           default:
-            if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
-              return;
-            }
+            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
             break;
           case 10: {
             global::Google.Protobuf.WellKnownTypes.Any subBuilder = new global::Google.Protobuf.WellKnownTypes.Any();
@@ -2544,9 +2538,7 @@
       while ((tag = input.ReadTag()) != 0) {
         switch(tag) {
           default:
-            if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
-              return;
-            }
+            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
             break;
           case 10: {
             anyField_.AddEntriesFrom(input, _map_anyField_codec);
diff --git a/csharp/src/Google.Protobuf.Test/WellKnownTypes/TimestampTest.cs b/csharp/src/Google.Protobuf.Test/WellKnownTypes/TimestampTest.cs
index b8c07ef..ffc6041 100644
--- a/csharp/src/Google.Protobuf.Test/WellKnownTypes/TimestampTest.cs
+++ b/csharp/src/Google.Protobuf.Test/WellKnownTypes/TimestampTest.cs
@@ -99,7 +99,7 @@
             Duration difference = new Duration { Seconds = 1999, Nanos = Duration.NanosecondsPerSecond - 5000 };
             Assert.AreEqual(difference, t1 - t2);
             Assert.AreEqual(-difference, t2 - t1);
-            
+
             Assert.AreEqual(t1, t2 + difference);
             Assert.AreEqual(t2, t1 - difference);
         }
@@ -190,7 +190,7 @@
             Assert.IsTrue(e > d);
             Assert.IsTrue(e == e);
             Assert.IsTrue(e == e.Clone());
-            
+
             Assert.IsTrue(b >= a);
             Assert.IsTrue(b <= c);
             Assert.IsTrue(b <= d);
diff --git a/csharp/src/Google.Protobuf.Test/WellKnownTypes/WrappersTest.cs b/csharp/src/Google.Protobuf.Test/WellKnownTypes/WrappersTest.cs
index 8ed5574..8a9c3d0 100644
--- a/csharp/src/Google.Protobuf.Test/WellKnownTypes/WrappersTest.cs
+++ b/csharp/src/Google.Protobuf.Test/WellKnownTypes/WrappersTest.cs
@@ -135,7 +135,7 @@
                 DoubleField = { 12.5, -1.5, 0d },
                 FloatField = { 123.25f, -20f, 0f },
                 Int32Field = { int.MaxValue, int.MinValue, 0 },
-                Int64Field = { long.MaxValue, long.MinValue, 0L },                
+                Int64Field = { long.MaxValue, long.MinValue, 0L },
                 StringField = { "First", "Second", "" },
                 Uint32Field = { uint.MaxValue, uint.MinValue, 0U },
                 Uint64Field = { ulong.MaxValue, ulong.MinValue, 0UL },
@@ -403,7 +403,7 @@
 
             output.Flush();
             stream.Position = 0;
-            
+
             var message = TestWellKnownTypes.Parser.ParseFrom(stream);
             Assert.AreEqual(6, message.Int32Field);
         }
diff --git a/csharp/src/Google.Protobuf/FieldCodec.cs b/csharp/src/Google.Protobuf/FieldCodec.cs
index 221ad5f..0610521 100644
--- a/csharp/src/Google.Protobuf/FieldCodec.cs
+++ b/csharp/src/Google.Protobuf/FieldCodec.cs
@@ -292,7 +292,7 @@
 
             /// <summary>
             /// Returns a field codec which effectively wraps a value of type T in a message.
-            /// 
+            ///
             /// </summary>
             internal static FieldCodec<T> GetCodec<T>()
             {
@@ -431,7 +431,7 @@
         internal T DefaultValue { get; }
 
         private readonly int tagSize;
-        
+
         internal FieldCodec(
                 Func<CodedInputStream, T> reader,
                 Action<CodedOutputStream, T> writer,
diff --git a/csharp/src/Google.Protobuf/FieldMaskTree.cs b/csharp/src/Google.Protobuf/FieldMaskTree.cs
index ff9e088..2297e7a 100644
--- a/csharp/src/Google.Protobuf/FieldMaskTree.cs
+++ b/csharp/src/Google.Protobuf/FieldMaskTree.cs
@@ -41,7 +41,7 @@
     /// <summary>
     /// <para>A tree representation of a FieldMask. Each leaf node in this tree represent
     /// a field path in the FieldMask.</para>
-    /// 
+    ///
     /// <para>For example, FieldMask "foo.bar,foo.baz,bar.baz" as a tree will be:</para>
     /// <code>
     ///   [root] -+- foo -+- bar
@@ -50,7 +50,7 @@
     ///           |
     ///           +- bar --- baz
     /// </code>
-    /// 
+    ///
     /// <para>By representing FieldMasks with this tree structure we can easily convert
     /// a FieldMask to a canonical form, merge two FieldMasks, calculate the
     /// intersection to two FieldMasks and traverse all fields specified by the
@@ -242,7 +242,7 @@
 
             Merge(root, "", source, destination, options);
         }
-        
+
         /// <summary>
         /// Merges all fields specified by a sub-tree from <paramref name="source"/> to <paramref name="destination"/>.
         /// </summary>
diff --git a/csharp/src/Google.Protobuf/Google.Protobuf.csproj b/csharp/src/Google.Protobuf/Google.Protobuf.csproj
index 8306c74..9c8edc1 100644
--- a/csharp/src/Google.Protobuf/Google.Protobuf.csproj
+++ b/csharp/src/Google.Protobuf/Google.Protobuf.csproj
@@ -20,7 +20,7 @@
     <RepositoryUrl>https://github.com/protocolbuffers/protobuf.git</RepositoryUrl>
   </PropertyGroup>
 
-  <!-- 
+  <!--
     - Override target frameworks on non-Windows to just .NET Core
     - Doing this conditionally in the initial PropertyGroup confuses
     - Visual Studio.
@@ -30,7 +30,7 @@
   </PropertyGroup>
 
   <ItemGroup>
-    <PackageReference Include="SourceLink.Create.CommandLine" PrivateAssets="All" Version="2.7.6"/> 
+    <PackageReference Include="SourceLink.Create.CommandLine" PrivateAssets="All" Version="2.7.6"/>
   </ItemGroup>
 
 </Project>
diff --git a/csharp/src/Google.Protobuf/JsonFormatter.cs b/csharp/src/Google.Protobuf/JsonFormatter.cs
index 31fd887..2b4c5f0 100644
--- a/csharp/src/Google.Protobuf/JsonFormatter.cs
+++ b/csharp/src/Google.Protobuf/JsonFormatter.cs
@@ -70,7 +70,7 @@
         /// </summary>
         public static JsonFormatter Default { get; } = new JsonFormatter(Settings.Default);
 
-        // A JSON formatter which *only* exists 
+        // A JSON formatter which *only* exists
         private static readonly JsonFormatter diagnosticFormatter = new JsonFormatter(Settings.Default);
 
         /// <summary>
@@ -579,7 +579,7 @@
             writer.Write(data.ToBase64());
             writer.Write('"');
             writer.Write(" }");
-        }        
+        }
 
         private void WriteStruct(TextWriter writer, IMessage message)
         {
@@ -616,7 +616,7 @@
             }
 
             object value = specifiedField.Accessor.GetValue(message);
-            
+
             switch (specifiedField.FieldNumber)
             {
                 case Value.BoolValueFieldNumber:
@@ -871,7 +871,7 @@
             // the platforms we target have it.
             private static readonly Dictionary<System.Type, Dictionary<object, string>> dictionaries
                 = new Dictionary<System.Type, Dictionary<object, string>>();
-            
+
             internal static string GetOriginalName(object value)
             {
                 var enumType = value.GetType();
diff --git a/csharp/src/Google.Protobuf/JsonParser.cs b/csharp/src/Google.Protobuf/JsonParser.cs
index 284bce9..fb594f2 100644
--- a/csharp/src/Google.Protobuf/JsonParser.cs
+++ b/csharp/src/Google.Protobuf/JsonParser.cs
@@ -674,7 +674,7 @@
             if (value != Math.Floor(value))
             {
                 throw new InvalidProtocolBufferException($"Value not an integer: {value}");
-            }            
+            }
         }
 
         private static object ParseSingleStringValue(FieldDescriptor field, string text)
@@ -919,7 +919,7 @@
                 messagePaths.Add(ToSnakeCase(path));
             }
         }
-        
+
         // Ported from src/google/protobuf/util/internal/utility.cc
         private static string ToSnakeCase(string text)
         {
diff --git a/csharp/src/Google.Protobuf/JsonTokenizer.cs b/csharp/src/Google.Protobuf/JsonTokenizer.cs
index 0e403f7..4725e7c 100644
--- a/csharp/src/Google.Protobuf/JsonTokenizer.cs
+++ b/csharp/src/Google.Protobuf/JsonTokenizer.cs
@@ -614,7 +614,7 @@
             /// where ^ represents the current position within the text stream. The examples all use string values,
             /// but could be any value, including nested objects/arrays.
             /// The complete state of the tokenizer also includes a stack to indicate the contexts (arrays/objects).
-            /// Any additional notional state of "AfterValue" indicates that a value has been completed, at which 
+            /// Any additional notional state of "AfterValue" indicates that a value has been completed, at which
             /// point there's an immediate transition to ExpectedEndOfDocument,  ObjectAfterProperty or ArrayAfterValue.
             /// </para>
             /// <para>
@@ -655,7 +655,7 @@
                 /// <summary>
                 /// { "foo" : ^ "bar", "x": "y" }
                 /// Before any property other than the first in an object.
-                /// (Equivalently: after any property in an object) 
+                /// (Equivalently: after any property in an object)
                 /// Next states:
                 /// "AfterValue" (value is simple)
                 /// ObjectStart (value is object)
diff --git a/csharp/src/Google.Protobuf/LimitedInputStream.cs b/csharp/src/Google.Protobuf/LimitedInputStream.cs
index f11d19d..50ead9c 100644
--- a/csharp/src/Google.Protobuf/LimitedInputStream.cs
+++ b/csharp/src/Google.Protobuf/LimitedInputStream.cs
@@ -29,7 +29,7 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #endregion
-    
+
 using System;
 using System.IO;
 
diff --git a/csharp/src/Google.Protobuf/MessageExtensions.cs b/csharp/src/Google.Protobuf/MessageExtensions.cs
index e1c57dc..7b13aa7 100644
--- a/csharp/src/Google.Protobuf/MessageExtensions.cs
+++ b/csharp/src/Google.Protobuf/MessageExtensions.cs
@@ -163,12 +163,12 @@
                         var map = (IDictionary)f.Accessor.GetValue(message);
                         return map.Values.OfType<IMessage>().All(IsInitialized);
                     }
-                    else if (f.IsRepeated && f.MessageType != null)
+                    else if (f.IsRepeated && f.FieldType == FieldType.Message || f.FieldType == FieldType.Group)
                     {
                         var enumerable = (IEnumerable)f.Accessor.GetValue(message);
                         return enumerable.Cast<IMessage>().All(IsInitialized);
                     }
-                    else if (f.MessageType != null)
+                    else if (f.FieldType == FieldType.Message || f.FieldType == FieldType.Group)
                     {
                         if (f.Accessor.HasValue(message))
                         {
@@ -183,7 +183,7 @@
                     {
                         return f.Accessor.HasValue(message);
                     }
-                    else 
+                    else
                     {
                         return true;
                     }
diff --git a/csharp/src/Google.Protobuf/MessageParser.cs b/csharp/src/Google.Protobuf/MessageParser.cs
index d3fa6cb..7e9c988 100644
--- a/csharp/src/Google.Protobuf/MessageParser.cs
+++ b/csharp/src/Google.Protobuf/MessageParser.cs
@@ -29,7 +29,7 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #endregion
-    
+
 using System;
 using System.IO;
 
@@ -210,7 +210,7 @@
         // The current implementation avoids a virtual method call and a cast, which *may* be significant in some cases.
         // Benchmarking work is required to measure the significance - but it's only a few lines of code in any case.
         // The API wouldn't change anyway - just the implementation - so this work can be deferred.
-        private readonly Func<T> factory; 
+        private readonly Func<T> factory;
 
         /// <summary>
         /// Creates a new parser.
diff --git a/csharp/src/Google.Protobuf/Reflection/CustomOptions.cs b/csharp/src/Google.Protobuf/Reflection/CustomOptions.cs
index 88b3ec0..82e59cd 100644
--- a/csharp/src/Google.Protobuf/Reflection/CustomOptions.cs
+++ b/csharp/src/Google.Protobuf/Reflection/CustomOptions.cs
@@ -63,7 +63,7 @@
         /// Singleton for all descriptors with an empty set of options.
         /// </summary>
         internal static readonly CustomOptions Empty = new CustomOptions();
-        
+
         /// <summary>
         /// A sequence of values per field. This needs to be per field rather than per tag to allow correct deserialization
         /// of repeated fields which could be "int, ByteString, int" - unlikely as that is. The fact that values are boxed
@@ -147,7 +147,7 @@
         /// <param name="value">The output variable to populate.</param>
         /// <returns><c>true</c> if a suitable value for the field was found; <c>false</c> otherwise.</returns>
         public bool TryGetSFixed64(int field, out long value) => TryGetInt64(field, out value);
-        
+
         /// <summary>
         /// Retrieves a signed 32-bit integer value for the specified option field,
         /// assuming a zigzag encoding.
@@ -357,7 +357,7 @@
             List<FieldValue> valuesForField;
             if (!ret.valuesByField.TryGetValue(field, out valuesForField))
             {
-                // Expect almost all 
+                // Expect almost all
                 valuesForField = new List<FieldValue>(1);
                 ret.valuesByField[field] = valuesForField;
             }
diff --git a/csharp/src/Google.Protobuf/Reflection/Descriptor.cs b/csharp/src/Google.Protobuf/Reflection/Descriptor.cs
index f101cd3..0c33e63 100644
--- a/csharp/src/Google.Protobuf/Reflection/Descriptor.cs
+++ b/csharp/src/Google.Protobuf/Reflection/Descriptor.cs
@@ -302,9 +302,7 @@
       while ((tag = input.ReadTag()) != 0) {
         switch(tag) {
           default:
-            if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
-              return;
-            }
+            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
             break;
           case 10: {
             file_.AddEntriesFrom(input, _repeated_file_codec);
@@ -735,9 +733,7 @@
       while ((tag = input.ReadTag()) != 0) {
         switch(tag) {
           default:
-            if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
-              return;
-            }
+            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
             break;
           case 10: {
             Name = input.ReadString();
@@ -1102,9 +1098,7 @@
       while ((tag = input.ReadTag()) != 0) {
         switch(tag) {
           default:
-            if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
-              return;
-            }
+            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
             break;
           case 10: {
             Name = input.ReadString();
@@ -1363,9 +1357,7 @@
           while ((tag = input.ReadTag()) != 0) {
             switch(tag) {
               default:
-                if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
-                  return;
-                }
+                _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
                 break;
               case 8: {
                 Start = input.ReadInt32();
@@ -1568,9 +1560,7 @@
           while ((tag = input.ReadTag()) != 0) {
             switch(tag) {
               default:
-                if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
-                  return;
-                }
+                _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
                 break;
               case 8: {
                 Start = input.ReadInt32();
@@ -1703,9 +1693,7 @@
       while ((tag = input.ReadTag()) != 0) {
         switch(tag) {
           default:
-            if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
-              return;
-            }
+            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
             break;
           case 7994: {
             uninterpretedOption_.AddEntriesFrom(input, _repeated_uninterpretedOption_codec);
@@ -2212,9 +2200,7 @@
       while ((tag = input.ReadTag()) != 0) {
         switch(tag) {
           default:
-            if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
-              return;
-            }
+            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
             break;
           case 10: {
             Name = input.ReadString();
@@ -2501,9 +2487,7 @@
       while ((tag = input.ReadTag()) != 0) {
         switch(tag) {
           default:
-            if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
-              return;
-            }
+            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
             break;
           case 10: {
             Name = input.ReadString();
@@ -2748,9 +2732,7 @@
       while ((tag = input.ReadTag()) != 0) {
         switch(tag) {
           default:
-            if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
-              return;
-            }
+            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
             break;
           case 10: {
             Name = input.ReadString();
@@ -2966,9 +2948,7 @@
           while ((tag = input.ReadTag()) != 0) {
             switch(tag) {
               default:
-                if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
-                  return;
-                }
+                _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
                 break;
               case 8: {
                 Start = input.ReadInt32();
@@ -3197,9 +3177,7 @@
       while ((tag = input.ReadTag()) != 0) {
         switch(tag) {
           default:
-            if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
-              return;
-            }
+            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
             break;
           case 10: {
             Name = input.ReadString();
@@ -3407,9 +3385,7 @@
       while ((tag = input.ReadTag()) != 0) {
         switch(tag) {
           default:
-            if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
-              return;
-            }
+            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
             break;
           case 10: {
             Name = input.ReadString();
@@ -3759,9 +3735,7 @@
       while ((tag = input.ReadTag()) != 0) {
         switch(tag) {
           default:
-            if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
-              return;
-            }
+            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
             break;
           case 10: {
             Name = input.ReadString();
@@ -6949,9 +6923,7 @@
       while ((tag = input.ReadTag()) != 0) {
         switch(tag) {
           default:
-            if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
-              return;
-            }
+            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
             break;
           case 18: {
             name_.AddEntriesFrom(input, _repeated_name_codec);
@@ -7164,9 +7136,7 @@
           while ((tag = input.ReadTag()) != 0) {
             switch(tag) {
               default:
-                if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
-                  return;
-                }
+                _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
                 break;
               case 10: {
                 NamePart_ = input.ReadString();
@@ -7345,9 +7315,7 @@
       while ((tag = input.ReadTag()) != 0) {
         switch(tag) {
           default:
-            if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
-              return;
-            }
+            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
             break;
           case 10: {
             location_.AddEntriesFrom(input, _repeated_location_codec);
@@ -7655,9 +7623,7 @@
           while ((tag = input.ReadTag()) != 0) {
             switch(tag) {
               default:
-                if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
-                  return;
-                }
+                _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
                 break;
               case 10:
               case 8: {
@@ -7810,9 +7776,7 @@
       while ((tag = input.ReadTag()) != 0) {
         switch(tag) {
           default:
-            if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
-              return;
-            }
+            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
             break;
           case 10: {
             annotation_.AddEntriesFrom(input, _repeated_annotation_codec);
@@ -8063,9 +8027,7 @@
           while ((tag = input.ReadTag()) != 0) {
             switch(tag) {
               default:
-                if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
-                  return;
-                }
+                _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
                 break;
               case 10:
               case 8: {
diff --git a/csharp/src/Google.Protobuf/Reflection/DescriptorBase.cs b/csharp/src/Google.Protobuf/Reflection/DescriptorBase.cs
index bfbebf1..6befbf1 100644
--- a/csharp/src/Google.Protobuf/Reflection/DescriptorBase.cs
+++ b/csharp/src/Google.Protobuf/Reflection/DescriptorBase.cs
@@ -47,7 +47,7 @@
         }
 
         /// <value>
-        /// The index of this descriptor within its parent descriptor. 
+        /// The index of this descriptor within its parent descriptor.
         /// </value>
         /// <remarks>
         /// This returns the index of this descriptor within its parent, for
diff --git a/csharp/src/Google.Protobuf/Reflection/EnumValueDescriptor.cs b/csharp/src/Google.Protobuf/Reflection/EnumValueDescriptor.cs
index 8b838c6..8a14b87 100644
--- a/csharp/src/Google.Protobuf/Reflection/EnumValueDescriptor.cs
+++ b/csharp/src/Google.Protobuf/Reflection/EnumValueDescriptor.cs
@@ -35,7 +35,7 @@
     /// <summary>
     /// Descriptor for a single enum value within an enum in a .proto file.
     /// </summary>
-    public sealed class EnumValueDescriptor : DescriptorBase                                            
+    public sealed class EnumValueDescriptor : DescriptorBase
     {
         private readonly EnumDescriptor enumDescriptor;
         private readonly EnumValueDescriptorProto proto;
diff --git a/csharp/src/Google.Protobuf/Reflection/FieldDescriptor.cs b/csharp/src/Google.Protobuf/Reflection/FieldDescriptor.cs
index 0a46f9e..5ad192e 100644
--- a/csharp/src/Google.Protobuf/Reflection/FieldDescriptor.cs
+++ b/csharp/src/Google.Protobuf/Reflection/FieldDescriptor.cs
@@ -98,7 +98,7 @@
             this.propertyName = propertyName;
             JsonName =  Proto.JsonName == "" ? JsonFormatter.ToJsonName(Proto.Name) : Proto.JsonName;
         }
-    
+
 
         /// <summary>
         /// The brief name of the descriptor's target.
@@ -129,7 +129,7 @@
         /// </para>
         /// </remarks>
         public IFieldAccessor Accessor => accessor;
-        
+
         /// <summary>
         /// Maps a field type as included in the .proto file to a FieldType.
         /// </summary>
diff --git a/csharp/src/Google.Protobuf/Reflection/IDescriptor.cs b/csharp/src/Google.Protobuf/Reflection/IDescriptor.cs
index 318d58c..1c1ef38 100644
--- a/csharp/src/Google.Protobuf/Reflection/IDescriptor.cs
+++ b/csharp/src/Google.Protobuf/Reflection/IDescriptor.cs
@@ -51,5 +51,5 @@
         /// Returns the descriptor for the .proto file that this entity is part of.
         /// </summary>
         FileDescriptor File { get; }
-    }    
+    }
 }
\ No newline at end of file
diff --git a/csharp/src/Google.Protobuf/Reflection/MessageDescriptor.cs b/csharp/src/Google.Protobuf/Reflection/MessageDescriptor.cs
index 03fd63c..68722d4 100644
--- a/csharp/src/Google.Protobuf/Reflection/MessageDescriptor.cs
+++ b/csharp/src/Google.Protobuf/Reflection/MessageDescriptor.cs
@@ -63,7 +63,7 @@
         private readonly IList<FieldDescriptor> fieldsInDeclarationOrder;
         private readonly IList<FieldDescriptor> fieldsInNumberOrder;
         private readonly IDictionary<string, FieldDescriptor> jsonFieldMap;
-        
+
         internal MessageDescriptor(DescriptorProto proto, FileDescriptor file, MessageDescriptor parent, int typeIndex, GeneratedClrTypeInfo generatedCodeInfo)
             : base(file, file.ComputeFullName(parent, proto.Name), typeIndex)
         {
diff --git a/csharp/src/Google.Protobuf/Reflection/OneofAccessor.cs b/csharp/src/Google.Protobuf/Reflection/OneofAccessor.cs
index 9759621..f4bf628 100644
--- a/csharp/src/Google.Protobuf/Reflection/OneofAccessor.cs
+++ b/csharp/src/Google.Protobuf/Reflection/OneofAccessor.cs
@@ -45,7 +45,7 @@
         private readonly Action<IMessage> clearDelegate;
         private OneofDescriptor descriptor;
 
-        internal OneofAccessor(PropertyInfo caseProperty, MethodInfo clearMethod, OneofDescriptor descriptor) 
+        internal OneofAccessor(PropertyInfo caseProperty, MethodInfo clearMethod, OneofDescriptor descriptor)
         {
             if (!caseProperty.CanRead)
             {
diff --git a/csharp/src/Google.Protobuf/Reflection/OriginalNameAttribute.cs b/csharp/src/Google.Protobuf/Reflection/OriginalNameAttribute.cs
index 07d0fd9..63f5228 100644
--- a/csharp/src/Google.Protobuf/Reflection/OriginalNameAttribute.cs
+++ b/csharp/src/Google.Protobuf/Reflection/OriginalNameAttribute.cs
@@ -60,6 +60,6 @@
             Name = ProtoPreconditions.CheckNotNull(name, nameof(name));
             PreferredAlias = true;
         }
-	
+
     }
 }
diff --git a/csharp/src/Google.Protobuf/Reflection/SingleFieldAccessor.cs b/csharp/src/Google.Protobuf/Reflection/SingleFieldAccessor.cs
index 5872ee2..dfc5b62 100644
--- a/csharp/src/Google.Protobuf/Reflection/SingleFieldAccessor.cs
+++ b/csharp/src/Google.Protobuf/Reflection/SingleFieldAccessor.cs
@@ -77,7 +77,7 @@
                 };
                 var clrType = property.PropertyType;
 
-                // TODO: Validate that this is a reasonable single field? (Should be a value type, a message type, or string/ByteString.) 
+                // TODO: Validate that this is a reasonable single field? (Should be a value type, a message type, or string/ByteString.)
                 object defaultValue =
                     descriptor.FieldType == FieldType.Message ? null
                     : clrType == typeof(string) ? ""
diff --git a/csharp/src/Google.Protobuf/UnknownField.cs b/csharp/src/Google.Protobuf/UnknownField.cs
index 2b13fdb..e3ce0e8 100644
--- a/csharp/src/Google.Protobuf/UnknownField.cs
+++ b/csharp/src/Google.Protobuf/UnknownField.cs
@@ -171,7 +171,7 @@
             {
                 result += CodedOutputStream.ComputeTagSize(fieldNumber) * fixed64List.Count;
                 result += CodedOutputStream.ComputeFixed64Size(1) * fixed64List.Count;
-            }                
+            }
             if (lengthDelimitedList != null)
             {
                 result += CodedOutputStream.ComputeTagSize(fieldNumber) * lengthDelimitedList.Count;
@@ -266,7 +266,7 @@
             return this;
         }
 
-        internal UnknownField AddGroup(UnknownFieldSet value) 
+        internal UnknownField AddGroup(UnknownFieldSet value)
         {
             groupList = Add(groupList, value);
             return this;
diff --git a/csharp/src/Google.Protobuf/UnknownFieldSet.cs b/csharp/src/Google.Protobuf/UnknownFieldSet.cs
index 9121567..21ec13b 100644
--- a/csharp/src/Google.Protobuf/UnknownFieldSet.cs
+++ b/csharp/src/Google.Protobuf/UnknownFieldSet.cs
@@ -260,29 +260,6 @@
             }
             return unknownFields;
         }

-

-        /// <summary>
-        /// Create a new UnknownFieldSet if unknownFields is null.
-        /// Parse a single field from <paramref name="input"/> and merge it
-        /// into unknownFields. If <paramref name="input"/> is configured to discard unknown fields,
-        /// <paramref name="unknownFields"/> will be returned as-is and the field will be skipped.
-        /// </summary>
-        /// <param name="unknownFields">The UnknownFieldSet which need to be merged</param>
-        /// <param name="input">The coded input stream containing the field</param>
-        /// <returns>The merged UnknownFieldSet</returns>
-        public static bool MergeFieldFrom(ref UnknownFieldSet unknownFields, CodedInputStream input)

-        {

-            if (input.DiscardUnknownFields)

-            {

-                input.SkipLastField();

-                return true;

-            }

-            if (unknownFields == null)

-            {

-                unknownFields = new UnknownFieldSet();

-            }

-            return unknownFields.MergeFieldFrom(input);

-        }
 
         /// <summary>
         /// Merges the fields from <paramref name="other"/> into this set.
diff --git a/csharp/src/Google.Protobuf/WellKnownTypes/Any.cs b/csharp/src/Google.Protobuf/WellKnownTypes/Any.cs
index b1ed0bc..dd99110 100644
--- a/csharp/src/Google.Protobuf/WellKnownTypes/Any.cs
+++ b/csharp/src/Google.Protobuf/WellKnownTypes/Any.cs
@@ -292,9 +292,7 @@
       while ((tag = input.ReadTag()) != 0) {
         switch(tag) {
           default:
-            if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
-              return;
-            }
+            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
             break;
           case 10: {
             TypeUrl = input.ReadString();
diff --git a/csharp/src/Google.Protobuf/WellKnownTypes/AnyPartial.cs b/csharp/src/Google.Protobuf/WellKnownTypes/AnyPartial.cs
index b951c13..49f2599 100644
--- a/csharp/src/Google.Protobuf/WellKnownTypes/AnyPartial.cs
+++ b/csharp/src/Google.Protobuf/WellKnownTypes/AnyPartial.cs
@@ -49,7 +49,7 @@
         /// </summary>
         /// <remarks>
         /// <para>
-        /// This is always just the last part of the URL, after the final slash. No validation of 
+        /// This is always just the last part of the URL, after the final slash. No validation of
         /// anything before the trailing slash is performed. If the type URL does not include a slash,
         /// an empty string is returned rather than an exception being thrown; this won't match any types,
         /// and the calling code is probably in a better position to give a meaningful error.
diff --git a/csharp/src/Google.Protobuf/WellKnownTypes/Api.cs b/csharp/src/Google.Protobuf/WellKnownTypes/Api.cs
index a566e40..438e1db 100644
--- a/csharp/src/Google.Protobuf/WellKnownTypes/Api.cs
+++ b/csharp/src/Google.Protobuf/WellKnownTypes/Api.cs
@@ -345,9 +345,7 @@
       while ((tag = input.ReadTag()) != 0) {
         switch(tag) {
           default:
-            if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
-              return;
-            }
+            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
             break;
           case 10: {
             Name = input.ReadString();
@@ -663,9 +661,7 @@
       while ((tag = input.ReadTag()) != 0) {
         switch(tag) {
           default:
-            if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
-              return;
-            }
+            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
             break;
           case 10: {
             Name = input.ReadString();
@@ -929,9 +925,7 @@
       while ((tag = input.ReadTag()) != 0) {
         switch(tag) {
           default:
-            if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
-              return;
-            }
+            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
             break;
           case 10: {
             Name = input.ReadString();
diff --git a/csharp/src/Google.Protobuf/WellKnownTypes/Duration.cs b/csharp/src/Google.Protobuf/WellKnownTypes/Duration.cs
index 691ca33..2858b53 100644
--- a/csharp/src/Google.Protobuf/WellKnownTypes/Duration.cs
+++ b/csharp/src/Google.Protobuf/WellKnownTypes/Duration.cs
@@ -254,9 +254,7 @@
       while ((tag = input.ReadTag()) != 0) {
         switch(tag) {
           default:
-            if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
-              return;
-            }
+            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
             break;
           case 8: {
             Seconds = input.ReadInt64();
diff --git a/csharp/src/Google.Protobuf/WellKnownTypes/DurationPartial.cs b/csharp/src/Google.Protobuf/WellKnownTypes/DurationPartial.cs
index f164bfd..9a468fc 100644
--- a/csharp/src/Google.Protobuf/WellKnownTypes/DurationPartial.cs
+++ b/csharp/src/Google.Protobuf/WellKnownTypes/DurationPartial.cs
@@ -156,7 +156,7 @@
                 return Normalize(lhs.Seconds - rhs.Seconds, lhs.Nanos - rhs.Nanos);
             }
         }
-        
+
         /// <summary>
         /// Creates a duration with the normalized values from the given number of seconds and
         /// nanoseconds, conforming with the description in the proto file.
diff --git a/csharp/src/Google.Protobuf/WellKnownTypes/Empty.cs b/csharp/src/Google.Protobuf/WellKnownTypes/Empty.cs
index 03ffc4a..2113add 100644
--- a/csharp/src/Google.Protobuf/WellKnownTypes/Empty.cs
+++ b/csharp/src/Google.Protobuf/WellKnownTypes/Empty.cs
@@ -143,9 +143,7 @@
       while ((tag = input.ReadTag()) != 0) {
         switch(tag) {
           default:
-            if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
-              return;
-            }
+            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
             break;
         }
       }
diff --git a/csharp/src/Google.Protobuf/WellKnownTypes/FieldMask.cs b/csharp/src/Google.Protobuf/WellKnownTypes/FieldMask.cs
index 8114aa3..6ad31a5 100644
--- a/csharp/src/Google.Protobuf/WellKnownTypes/FieldMask.cs
+++ b/csharp/src/Google.Protobuf/WellKnownTypes/FieldMask.cs
@@ -352,9 +352,7 @@
       while ((tag = input.ReadTag()) != 0) {
         switch(tag) {
           default:
-            if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
-              return;
-            }
+            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
             break;
           case 10: {
             paths_.AddEntriesFrom(input, _repeated_paths_codec);
diff --git a/csharp/src/Google.Protobuf/WellKnownTypes/FieldMaskPartial.cs b/csharp/src/Google.Protobuf/WellKnownTypes/FieldMaskPartial.cs
index 27e513c..91d2ee9 100644
--- a/csharp/src/Google.Protobuf/WellKnownTypes/FieldMaskPartial.cs
+++ b/csharp/src/Google.Protobuf/WellKnownTypes/FieldMaskPartial.cs
@@ -358,7 +358,7 @@
             /// field is set in the source, the value is copied to the
             /// destination; if the field is unset in the source, the field is cleared
             /// from the destination) when merging.
-            /// 
+            ///
             /// Default behavior is to always set the value of the source primitive
             /// field to the destination primitive field, and if the source field is
             /// unset, the default value of the source field is copied to the
diff --git a/csharp/src/Google.Protobuf/WellKnownTypes/SourceContext.cs b/csharp/src/Google.Protobuf/WellKnownTypes/SourceContext.cs
index 2cae686..124ddaa 100644
--- a/csharp/src/Google.Protobuf/WellKnownTypes/SourceContext.cs
+++ b/csharp/src/Google.Protobuf/WellKnownTypes/SourceContext.cs
@@ -165,9 +165,7 @@
       while ((tag = input.ReadTag()) != 0) {
         switch(tag) {
           default:
-            if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
-              return;
-            }
+            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
             break;
           case 10: {
             FileName = input.ReadString();
diff --git a/csharp/src/Google.Protobuf/WellKnownTypes/Struct.cs b/csharp/src/Google.Protobuf/WellKnownTypes/Struct.cs
index 9667472..194b81e 100644
--- a/csharp/src/Google.Protobuf/WellKnownTypes/Struct.cs
+++ b/csharp/src/Google.Protobuf/WellKnownTypes/Struct.cs
@@ -189,9 +189,7 @@
       while ((tag = input.ReadTag()) != 0) {
         switch(tag) {
           default:
-            if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
-              return;
-            }
+            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
             break;
           case 10: {
             fields_.AddEntriesFrom(input, _map_fields_codec);
@@ -515,9 +513,7 @@
       while ((tag = input.ReadTag()) != 0) {
         switch(tag) {
           default:
-            if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
-              return;
-            }
+            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
             break;
           case 8: {
             kind_ = input.ReadEnum();
@@ -677,9 +673,7 @@
       while ((tag = input.ReadTag()) != 0) {
         switch(tag) {
           default:
-            if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
-              return;
-            }
+            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
             break;
           case 10: {
             values_.AddEntriesFrom(input, _repeated_values_codec);
diff --git a/csharp/src/Google.Protobuf/WellKnownTypes/Timestamp.cs b/csharp/src/Google.Protobuf/WellKnownTypes/Timestamp.cs
index 524ac06..2e5809f 100644
--- a/csharp/src/Google.Protobuf/WellKnownTypes/Timestamp.cs
+++ b/csharp/src/Google.Protobuf/WellKnownTypes/Timestamp.cs
@@ -273,9 +273,7 @@
       while ((tag = input.ReadTag()) != 0) {
         switch(tag) {
           default:
-            if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
-              return;
-            }
+            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
             break;
           case 8: {
             Seconds = input.ReadInt64();
diff --git a/csharp/src/Google.Protobuf/WellKnownTypes/Type.cs b/csharp/src/Google.Protobuf/WellKnownTypes/Type.cs
index adea910..52bd343 100644
--- a/csharp/src/Google.Protobuf/WellKnownTypes/Type.cs
+++ b/csharp/src/Google.Protobuf/WellKnownTypes/Type.cs
@@ -328,9 +328,7 @@
       while ((tag = input.ReadTag()) != 0) {
         switch(tag) {
           default:
-            if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
-              return;
-            }
+            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
             break;
           case 10: {
             Name = input.ReadString();
@@ -725,9 +723,7 @@
       while ((tag = input.ReadTag()) != 0) {
         switch(tag) {
           default:
-            if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
-              return;
-            }
+            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
             break;
           case 8: {
             Kind = (global::Google.Protobuf.WellKnownTypes.Field.Types.Kind) input.ReadEnum();
@@ -1104,9 +1100,7 @@
       while ((tag = input.ReadTag()) != 0) {
         switch(tag) {
           default:
-            if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
-              return;
-            }
+            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
             break;
           case 10: {
             Name = input.ReadString();
@@ -1306,9 +1300,7 @@
       while ((tag = input.ReadTag()) != 0) {
         switch(tag) {
           default:
-            if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
-              return;
-            }
+            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
             break;
           case 10: {
             Name = input.ReadString();
@@ -1488,9 +1480,7 @@
       while ((tag = input.ReadTag()) != 0) {
         switch(tag) {
           default:
-            if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
-              return;
-            }
+            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
             break;
           case 10: {
             Name = input.ReadString();
diff --git a/csharp/src/Google.Protobuf/WellKnownTypes/Wrappers.cs b/csharp/src/Google.Protobuf/WellKnownTypes/Wrappers.cs
index 679eb0f..25a65aa 100644
--- a/csharp/src/Google.Protobuf/WellKnownTypes/Wrappers.cs
+++ b/csharp/src/Google.Protobuf/WellKnownTypes/Wrappers.cs
@@ -177,9 +177,7 @@
       while ((tag = input.ReadTag()) != 0) {
         switch(tag) {
           default:
-            if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
-              return;
-            }
+            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
             break;
           case 9: {
             Value = input.ReadDouble();
@@ -316,9 +314,7 @@
       while ((tag = input.ReadTag()) != 0) {
         switch(tag) {
           default:
-            if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
-              return;
-            }
+            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
             break;
           case 13: {
             Value = input.ReadFloat();
@@ -455,9 +451,7 @@
       while ((tag = input.ReadTag()) != 0) {
         switch(tag) {
           default:
-            if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
-              return;
-            }
+            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
             break;
           case 8: {
             Value = input.ReadInt64();
@@ -594,9 +588,7 @@
       while ((tag = input.ReadTag()) != 0) {
         switch(tag) {
           default:
-            if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
-              return;
-            }
+            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
             break;
           case 8: {
             Value = input.ReadUInt64();
@@ -733,9 +725,7 @@
       while ((tag = input.ReadTag()) != 0) {
         switch(tag) {
           default:
-            if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
-              return;
-            }
+            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
             break;
           case 8: {
             Value = input.ReadInt32();
@@ -872,9 +862,7 @@
       while ((tag = input.ReadTag()) != 0) {
         switch(tag) {
           default:
-            if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
-              return;
-            }
+            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
             break;
           case 8: {
             Value = input.ReadUInt32();
@@ -1011,9 +999,7 @@
       while ((tag = input.ReadTag()) != 0) {
         switch(tag) {
           default:
-            if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
-              return;
-            }
+            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
             break;
           case 8: {
             Value = input.ReadBool();
@@ -1150,9 +1136,7 @@
       while ((tag = input.ReadTag()) != 0) {
         switch(tag) {
           default:
-            if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
-              return;
-            }
+            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
             break;
           case 10: {
             Value = input.ReadString();
@@ -1289,9 +1273,7 @@
       while ((tag = input.ReadTag()) != 0) {
         switch(tag) {
           default:
-            if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
-              return;
-            }
+            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
             break;
           case 10: {
             Value = input.ReadBytes();
diff --git a/docs/options.md b/docs/options.md
index 9604dd5..c1775d1 100644
--- a/docs/options.md
+++ b/docs/options.md
@@ -192,7 +192,7 @@
 1. CGSN Mooring Project
    * Website: https://bitbucket.org/ooicgsn/cgsn-mooring
    * Extensions: 1058
-   
+
 1. Container Storage Interface
    * Website: https://github.com/container-storage-interface/spec
    * Extensions: 1059-1069
diff --git a/docs/performance.md b/docs/performance.md
index 065a361..03e27f6 100644
--- a/docs/performance.md
+++ b/docs/performance.md
@@ -9,16 +9,16 @@
     * **reuse** - This is for reusing the same message instance for parsing.
 * **Java** - For Java there're 3 kinds of parsing/Serialization ways:
 	* **byte[]** - This is for parsing from a Byte Array.
-    * **ByteString** - This is for parsing from a 
+    * **ByteString** - This is for parsing from a
     	com.google.protobuf.ByteString.
     * **InputStream** - This is for parsing from a InputStream
 * **Python** - For Pythong there're 3 kinds of python protobuf for testing:
-	* **C++-genereated-code** - This is for using cpp generated code of the 
+	* **C++-genereated-code** - This is for using cpp generated code of the
     	proto file as dynamic linked library.
 	* **C++-reflection** - This is for using cpp reflection, which there's no
-    	generated code, but still using cpp protobuf library as dynamic linked 
+    	generated code, but still using cpp protobuf library as dynamic linked
         library.
-	* **pure-Python** - This is for pure Python version, which don't link with 
+	* **pure-Python** - This is for pure Python version, which don't link with
     	any cpp protobuf library.
 
 ## Parsing performance
diff --git a/docs/third_party.md b/docs/third_party.md
index 94ce0ec..eedce15 100644
--- a/docs/third_party.md
+++ b/docs/third_party.md
@@ -19,7 +19,6 @@
 * C++: https://github.com/google/protobuf (Google-official implementation)
 * C/C++: http://spbc.sf.net/
 * C#: http://code.google.com/p/protobuf-csharp-port
-* C#: http://code.google.com/p/protosharp/
 * C#: https://silentorbit.com/protobuf/
 * C#/.NET/WCF/VB: http://code.google.com/p/protobuf-net/
 * Clojure: http://github.com/ninjudd/clojure-protobuf
@@ -39,6 +38,7 @@
 * Erlang: https://github.com/tomas-abrahamsson/gpb
 * Erlang: http://piqi.org/
 * Erlang: https://github.com/basho/erlang_protobuffs (no longer maintained, use gpb instead)
+* Hacklang/HHVM: https://github.com/y3llowcake/proto-hack
 * GDScript: https://github.com/oniksan/godobuf (Godot v3 engine plugin)
 * Go: https://github.com/golang/protobuf (Google-official implementation)
 * Go: https://github.com/akunspy/gopbuf
@@ -92,6 +92,7 @@
 * Solidity: https://github.com/celer-network/pb3-gen-sol
 * Swift: https://github.com/alexeyxo/protobuf-swift
 * Swift: https://github.com/apple/swift-protobuf/
+* Typescript: https://github.com/y3llowcake/protoc-gen-ts
 * Vala: https://launchpad.net/protobuf-vala
 * Visual Basic: http://code.google.com/p/protobuf-net/
 
@@ -171,4 +172,4 @@
 * [Make protoc plugins in NodeJS](https://github.com/konsumer/node-protoc-plugin)
 * [ProfaneDB - A Protocol Buffers database](https://profanedb.gitlab.io)
 * [Protocol Buffer property-based testing utility and example message generator (Python / Hypothesis)](https://github.com/CurataEng/hypothesis-protobuf)
-* [Protolock - CLI utility to prevent backward-incompatible changes to .proto files](https://github.com/nilslice/protolock) 
+* [Protolock - CLI utility to prevent backward-incompatible changes to .proto files](https://github.com/nilslice/protolock)
diff --git a/examples/list_people_test.go b/examples/list_people_test.go
index 64ea427..aceabd4 100644
--- a/examples/list_people_test.go
+++ b/examples/list_people_test.go
@@ -34,7 +34,7 @@
 
 func TestListPeopleWritesList(t *testing.T) {
 	buf := new(bytes.Buffer)
-	in := pb.AddressBook{People: []*pb.Person {
+	in := pb.AddressBook{People: []*pb.Person{
 		{
 			Name:  "John Doe",
 			Id:    101,
diff --git a/java/compatibility_tests/v2.5.0/more_protos/src/proto/google/protobuf/unittest_optimize_for.proto b/java/compatibility_tests/v2.5.0/more_protos/src/proto/google/protobuf/unittest_optimize_for.proto
index feecbef..658c6a9 100644
--- a/java/compatibility_tests/v2.5.0/more_protos/src/proto/google/protobuf/unittest_optimize_for.proto
+++ b/java/compatibility_tests/v2.5.0/more_protos/src/proto/google/protobuf/unittest_optimize_for.proto
@@ -55,7 +55,7 @@
 message TestRequiredOptimizedForSize {
   required int32 x = 1;
 }
- 
+
 message TestOptionalOptimizedForSize {
   optional TestRequiredOptimizedForSize o = 1;
 }
diff --git a/java/compatibility_tests/v2.5.0/protos/src/proto/google/protobuf/unittest_optimize_for.proto b/java/compatibility_tests/v2.5.0/protos/src/proto/google/protobuf/unittest_optimize_for.proto
index feecbef..658c6a9 100644
--- a/java/compatibility_tests/v2.5.0/protos/src/proto/google/protobuf/unittest_optimize_for.proto
+++ b/java/compatibility_tests/v2.5.0/protos/src/proto/google/protobuf/unittest_optimize_for.proto
@@ -55,7 +55,7 @@
 message TestRequiredOptimizedForSize {
   required int32 x = 1;
 }
- 
+
 message TestOptionalOptimizedForSize {
   optional TestRequiredOptimizedForSize o = 1;
 }
diff --git a/java/compatibility_tests/v2.5.0/tests/src/main/java/com/google/protobuf/test/ByteStringTest.java b/java/compatibility_tests/v2.5.0/tests/src/main/java/com/google/protobuf/test/ByteStringTest.java
index 8bb9f73..9e334e5 100644
--- a/java/compatibility_tests/v2.5.0/tests/src/main/java/com/google/protobuf/test/ByteStringTest.java
+++ b/java/compatibility_tests/v2.5.0/tests/src/main/java/com/google/protobuf/test/ByteStringTest.java
@@ -342,7 +342,7 @@
       return -1;
     }
   }
-  
+
   // A stream which exposes the byte array passed into write(byte[], int, int).
   private static class EvilOutputStream extends OutputStream {
     public byte[] capturedArray = null;
@@ -454,13 +454,13 @@
           isArrayRange(bytes, byteString.toByteArray(), 0, bytes.length));
     }
   }
-  
+
   public void testNewOutputEmpty() throws IOException {
     // Make sure newOutput() correctly builds empty byte strings
     ByteString byteString = ByteString.newOutput().toByteString();
     assertEquals(ByteString.EMPTY, byteString);
   }
-  
+
   public void testNewOutput_Mutating() throws IOException {
     Output os = ByteString.newOutput(5);
     os.write(new byte[] {1, 2, 3, 4, 5});
diff --git a/java/compatibility_tests/v2.5.0/tests/src/main/java/com/google/protobuf/test/DeprecatedFieldTest.java b/java/compatibility_tests/v2.5.0/tests/src/main/java/com/google/protobuf/test/DeprecatedFieldTest.java
index ee4e767..a7b7706 100644
--- a/java/compatibility_tests/v2.5.0/tests/src/main/java/com/google/protobuf/test/DeprecatedFieldTest.java
+++ b/java/compatibility_tests/v2.5.0/tests/src/main/java/com/google/protobuf/test/DeprecatedFieldTest.java
@@ -39,22 +39,22 @@
 import java.lang.reflect.Method;
 /**
  * Test field deprecation
- * 
+ *
  * @author birdo@google.com (Roberto Scaramuzzi)
  */
 public class DeprecatedFieldTest extends TestCase {
   private String[] deprecatedGetterNames = {
       "hasDeprecatedInt32",
       "getDeprecatedInt32"};
-  
+
   private String[] deprecatedBuilderGetterNames = {
       "hasDeprecatedInt32",
       "getDeprecatedInt32",
       "clearDeprecatedInt32"};
-  
+
   private String[] deprecatedBuilderSetterNames = {
-      "setDeprecatedInt32"}; 
-  
+      "setDeprecatedInt32"};
+
   public void testDeprecatedField() throws Exception {
     Class<?> deprecatedFields = TestDeprecatedFields.class;
     Class<?> deprecatedFieldsBuilder = TestDeprecatedFields.Builder.class;
@@ -74,7 +74,7 @@
           isDeprecated(method));
     }
   }
-  
+
   private boolean isDeprecated(AnnotatedElement annotated) {
     return annotated.isAnnotationPresent(Deprecated.class);
   }
diff --git a/java/compatibility_tests/v2.5.0/tests/src/main/java/com/google/protobuf/test/DescriptorsTest.java b/java/compatibility_tests/v2.5.0/tests/src/main/java/com/google/protobuf/test/DescriptorsTest.java
index aabd7b4..37e1ca7 100644
--- a/java/compatibility_tests/v2.5.0/tests/src/main/java/com/google/protobuf/test/DescriptorsTest.java
+++ b/java/compatibility_tests/v2.5.0/tests/src/main/java/com/google/protobuf/test/DescriptorsTest.java
@@ -490,7 +490,7 @@
       .build();
     // translate and crosslink
     FileDescriptor file =
-      Descriptors.FileDescriptor.buildFrom(fileDescriptorProto, 
+      Descriptors.FileDescriptor.buildFrom(fileDescriptorProto,
           new FileDescriptor[0]);
     // verify resulting descriptors
     assertNotNull(file);
@@ -511,7 +511,7 @@
     }
     assertTrue(barFound);
   }
-  
+
   public void testInvalidPublicDependency() throws Exception {
     FileDescriptorProto fooProto = FileDescriptorProto.newBuilder()
         .setName("foo.proto") .build();
@@ -595,7 +595,7 @@
     Descriptors.FileDescriptor.buildFrom(
         fooProto, new FileDescriptor[] {forwardFile});
   }
-  
+
   /**
    * Tests the translate/crosslink for an example with a more complex namespace
    * referencing.
@@ -644,6 +644,6 @@
       assertTrue(field.getEnumType().getFile().getName().equals("bar.proto"));
       assertTrue(field.getEnumType().getFile().getPackage().equals(
           "a.b.c.d.bar.shared"));
-    }   
+    }
   }
 }
diff --git a/java/compatibility_tests/v2.5.0/tests/src/main/java/com/google/protobuf/test/GeneratedMessageTest.java b/java/compatibility_tests/v2.5.0/tests/src/main/java/com/google/protobuf/test/GeneratedMessageTest.java
index 49f1146..1e7d41e 100644
--- a/java/compatibility_tests/v2.5.0/tests/src/main/java/com/google/protobuf/test/GeneratedMessageTest.java
+++ b/java/compatibility_tests/v2.5.0/tests/src/main/java/com/google/protobuf/test/GeneratedMessageTest.java
@@ -901,7 +901,7 @@
     FieldDescriptor fieldDescriptor =
         descriptor.findFieldByName("optional_nested_message");
 
-    // Before setting field, builder is initialized by default value. 
+    // Before setting field, builder is initialized by default value.
     TestAllTypes.Builder builder = TestAllTypes.newBuilder();
     NestedMessage.Builder fieldBuilder =
         (NestedMessage.Builder) builder.getFieldBuilder(fieldDescriptor);
diff --git a/java/compatibility_tests/v2.5.0/tests/src/main/java/com/google/protobuf/test/LiteralByteStringTest.java b/java/compatibility_tests/v2.5.0/tests/src/main/java/com/google/protobuf/test/LiteralByteStringTest.java
index b2dcc7e..5902ea3 100644
--- a/java/compatibility_tests/v2.5.0/tests/src/main/java/com/google/protobuf/test/LiteralByteStringTest.java
+++ b/java/compatibility_tests/v2.5.0/tests/src/main/java/com/google/protobuf/test/LiteralByteStringTest.java
@@ -233,7 +233,7 @@
     assertTrue(classUnderTest + ".writeTo() must give back the same bytes",
         Arrays.equals(referenceBytes, roundTripBytes));
   }
-  
+
   public void testWriteTo_mutating() throws IOException {
     OutputStream os = new OutputStream() {
       @Override
@@ -274,7 +274,7 @@
     assertEquals("Output.reset() resets the output", 0, output.size());
     assertEquals("Output.reset() resets the output",
         ByteString.EMPTY, output.toByteString());
-    
+
   }
 
   public void testHashCode() {
diff --git a/java/compatibility_tests/v2.5.0/tests/src/main/java/com/google/protobuf/test/MessageTest.java b/java/compatibility_tests/v2.5.0/tests/src/main/java/com/google/protobuf/test/MessageTest.java
index c8c95a8..629cabc 100644
--- a/java/compatibility_tests/v2.5.0/tests/src/main/java/com/google/protobuf/test/MessageTest.java
+++ b/java/compatibility_tests/v2.5.0/tests/src/main/java/com/google/protobuf/test/MessageTest.java
@@ -313,7 +313,7 @@
       assertEquals("Message missing required fields: a, b, c", e.getMessage());
     }
   }
-  
+
   /** Test reading unset repeated message from DynamicMessage. */
   public void testDynamicRepeatedMessageNull() throws Exception {
     Descriptors.Descriptor descriptor = TestRequired.getDescriptor();
@@ -327,7 +327,7 @@
     assertEquals(result.getRepeatedFieldCount(result.getDescriptorForType()
         .findFieldByName("repeated_foreign_message")), 0);
   }
-  
+
   /** Test reading repeated message from DynamicMessage. */
   public void testDynamicRepeatedMessageNotNull() throws Exception {
 
diff --git a/java/compatibility_tests/v2.5.0/tests/src/main/java/com/google/protobuf/test/RopeByteStringSubstringTest.java b/java/compatibility_tests/v2.5.0/tests/src/main/java/com/google/protobuf/test/RopeByteStringSubstringTest.java
index 3c1f503..c122385 100644
--- a/java/compatibility_tests/v2.5.0/tests/src/main/java/com/google/protobuf/test/RopeByteStringSubstringTest.java
+++ b/java/compatibility_tests/v2.5.0/tests/src/main/java/com/google/protobuf/test/RopeByteStringSubstringTest.java
@@ -36,7 +36,7 @@
 
 /**
  * This class tests {@link RopeByteString#substring(int, int)} by inheriting the tests from
- * {@link LiteralByteStringTest}.  Only a couple of methods are overridden.  
+ * {@link LiteralByteStringTest}.  Only a couple of methods are overridden.
  *
  * @author carlanton@google.com (Carl Haverl)
  */
diff --git a/java/compatibility_tests/v2.5.0/tests/src/main/java/com/google/protobuf/test/RopeByteStringTest.java b/java/compatibility_tests/v2.5.0/tests/src/main/java/com/google/protobuf/test/RopeByteStringTest.java
index 8caeadd..19098de 100644
--- a/java/compatibility_tests/v2.5.0/tests/src/main/java/com/google/protobuf/test/RopeByteStringTest.java
+++ b/java/compatibility_tests/v2.5.0/tests/src/main/java/com/google/protobuf/test/RopeByteStringTest.java
@@ -38,7 +38,7 @@
 /**
  * This class tests {@link RopeByteString} by inheriting the tests from
  * {@link LiteralByteStringTest}.  Only a couple of methods are overridden.
- * 
+ *
  * <p>A full test of the result of {@link RopeByteString#substring(int, int)} is found in the
  * separate class {@link RopeByteStringSubstringTest}.
  *
diff --git a/java/core/src/main/java/com/google/protobuf/GeneratedMessage.java b/java/core/src/main/java/com/google/protobuf/GeneratedMessage.java
index 60179e3..6713f43 100644
--- a/java/core/src/main/java/com/google/protobuf/GeneratedMessage.java
+++ b/java/core/src/main/java/com/google/protobuf/GeneratedMessage.java
@@ -3014,7 +3014,7 @@
 
     return (Extension<MessageType, T>) extension;
   }
-  
+
   protected static int computeStringSize(final int fieldNumber, final Object value) {
     if (value instanceof String) {
       return CodedOutputStream.computeStringSize(fieldNumber, (String) value);
@@ -3022,7 +3022,7 @@
       return CodedOutputStream.computeBytesSize(fieldNumber, (ByteString) value);
     }
   }
-  
+
   protected static int computeStringSizeNoTag(final Object value) {
     if (value instanceof String) {
       return CodedOutputStream.computeStringSizeNoTag((String) value);
@@ -3030,7 +3030,7 @@
       return CodedOutputStream.computeBytesSizeNoTag((ByteString) value);
     }
   }
-  
+
   protected static void writeString(
       CodedOutputStream output, final int fieldNumber, final Object value) throws IOException {
     if (value instanceof String) {
@@ -3039,7 +3039,7 @@
       output.writeBytes(fieldNumber, (ByteString) value);
     }
   }
-  
+
   protected static void writeStringNoTag(
       CodedOutputStream output, final Object value) throws IOException {
     if (value instanceof String) {
diff --git a/java/core/src/main/java/com/google/protobuf/GeneratedMessageV3.java b/java/core/src/main/java/com/google/protobuf/GeneratedMessageV3.java
index cacfa05..f75f325 100644
--- a/java/core/src/main/java/com/google/protobuf/GeneratedMessageV3.java
+++ b/java/core/src/main/java/com/google/protobuf/GeneratedMessageV3.java
@@ -364,7 +364,7 @@
       throw e.unwrapIOException();
     }
   }
-  
+
   protected static boolean canUseUnsafe() {
     return UnsafeUtil.hasUnsafeArrayOperations() && UnsafeUtil.hasUnsafeByteBufferOperations();
   }
diff --git a/java/lite.md b/java/lite.md
index 84a45ec..403d44f 100644
--- a/java/lite.md
+++ b/java/lite.md
@@ -21,7 +21,9 @@
 Choose the version that works on your platform (e.g., on windows you can
 download `protoc-gen-javalite-3.0.0-windows-x86_32.exe`), rename it to
 protoc-gen-javalite (or protoc-gen-javalite.exe on windows) and place it
-in a directory where it can be find in PATH.
+in a directory where it can be find in PATH. If you are using unix like OS
+then make sure to convert `protoc-gen-javalite` to unix executable. For example
+`chmod +x protoc-gen-javalite`
 
 Once you have the protoc and protoc plugin, you can generate Java Lite code
 for your .proto files:
diff --git a/java/util/src/test/java/com/google/protobuf/util/FieldMaskTreeTest.java b/java/util/src/test/java/com/google/protobuf/util/FieldMaskTreeTest.java
index a0d317d..b7addab 100644
--- a/java/util/src/test/java/com/google/protobuf/util/FieldMaskTreeTest.java
+++ b/java/util/src/test/java/com/google/protobuf/util/FieldMaskTreeTest.java
@@ -95,7 +95,7 @@
     tree.intersectFieldPath("bar", result);
     assertEquals("bar.baz,bar.quz,foo", result.toString());
   }
-  
+
   public void testMerge() throws Exception {
     testMergeImpl(true);
     testMergeImpl(false);
diff --git a/js/README.md b/js/README.md
index 2c14222..3635028 100644
--- a/js/README.md
+++ b/js/README.md
@@ -19,8 +19,8 @@
 To use Protocol Buffers with JavaScript, you need two main components:
 
 1. The protobuf runtime library.  You can install this with
-   `npm install google-protobuf`, or use the files in this directory.  
-    If npm is not being used, as of 3.3.0, the files needed are located in binary subdirectory; 
+   `npm install google-protobuf`, or use the files in this directory.
+    If npm is not being used, as of 3.3.0, the files needed are located in binary subdirectory;
     arith.js, constants.js, decoder.js, encoder.js, map.js, message.js, reader.js, utils.js, writer.js
 2. The Protocol Compiler `protoc`.  This translates `.proto` files
    into `.js` files.  The compiler is not currently available via
diff --git a/kokoro/linux/benchmark/continuous.cfg b/kokoro/linux/benchmark/continuous.cfg
index a3558c6..8cc8f96 100755
--- a/kokoro/linux/benchmark/continuous.cfg
+++ b/kokoro/linux/benchmark/continuous.cfg
@@ -2,7 +2,7 @@
 
 # Location of the build script in repository
 build_file: "protobuf/kokoro/linux/benchmark/build.sh"
-timeout_mins: 240 
+timeout_mins: 240
 
 action {
   define_artifacts {
diff --git a/kokoro/linux/benchmark/run.sh b/kokoro/linux/benchmark/run.sh
index 264bdaa..1b1032b 100755
--- a/kokoro/linux/benchmark/run.sh
+++ b/kokoro/linux/benchmark/run.sh
@@ -65,7 +65,7 @@
 env LD_PRELOAD="$oldpwd/gperftools/.libs/libtcmalloc.so" ./cpp-benchmark --benchmark_min_time=5.0 --benchmark_out_format=json --benchmark_out="tmp/cpp_result.json" $datasets
 cd $oldpwd
 
-# build go protobuf 
+# build go protobuf
 export PATH="`pwd`/src:$PATH"
 export GOPATH="$HOME/gocode"
 mkdir -p "$GOPATH/src/github.com/google"
diff --git a/kokoro/release/ruby/macos/ruby/ruby_build_environment.sh b/kokoro/release/ruby/macos/ruby/ruby_build_environment.sh
index c1645e0..d42a0a8 100755
--- a/kokoro/release/ruby/macos/ruby/ruby_build_environment.sh
+++ b/kokoro/release/ruby/macos/ruby/ruby_build_environment.sh
@@ -34,7 +34,7 @@
 +    '--without-gmp',
      '--with-ext='
    ]
- 
+
 @@ -151,6 +153,7 @@
  # make
  file "#{USER_HOME}/builds/#{MINGW_HOST}/#{RUBY_CC_VERSION}/ruby.exe" => ["#{USER_HOME}/builds/#{MINGW_HOST}/#{RUBY_CC_VERSION}/Makefile"] do |t|
diff --git a/objectivec/DevTools/full_mac_build.sh b/objectivec/DevTools/full_mac_build.sh
index 0de52bd..61d85c6 100755
--- a/objectivec/DevTools/full_mac_build.sh
+++ b/objectivec/DevTools/full_mac_build.sh
@@ -341,7 +341,7 @@
     xcodebuild
       -project objectivec/ProtocolBuffers_tvOS.xcodeproj
       -scheme ProtocolBuffers
-      # Test on the oldest and current. 
+      # Test on the oldest and current.
       -destination "platform=tvOS Simulator,name=Apple TV 1080p,OS=9.0"
       -destination "platform=tvOS Simulator,name=Apple TV,OS=latest"
   )
diff --git a/objectivec/GPBRuntimeTypes.h b/objectivec/GPBRuntimeTypes.h
index 4d55206..8148054 100644
--- a/objectivec/GPBRuntimeTypes.h
+++ b/objectivec/GPBRuntimeTypes.h
@@ -74,7 +74,7 @@
 
 /**
  * Enum listing the possible data types that a field can contain.
- * 
+ *
  * @note Do not change the order of this enum (or add things to it) without
  *       thinking about it very carefully. There are several things that depend
  *       on the order.
diff --git a/php/ext/google/protobuf/encode_decode.c b/php/ext/google/protobuf/encode_decode.c
index d7749196..fa7aeb1 100644
--- a/php/ext/google/protobuf/encode_decode.c
+++ b/php/ext/google/protobuf/encode_decode.c
@@ -265,7 +265,7 @@
       (stringfields_parseframe_t*)malloc(sizeof(stringfields_parseframe_t));
   frame->closure = closure;
   stringsink_init(&frame->sink);
-  
+
   return frame;
 }
 
@@ -376,7 +376,7 @@
       (stringfields_parseframe_t*)malloc(sizeof(stringfields_parseframe_t));
   frame->closure = closure;
   stringsink_init(&frame->sink);
-  
+
   return frame;
 }
 
@@ -791,7 +791,7 @@
       (stringfields_parseframe_t*)malloc(sizeof(stringfields_parseframe_t));
   frame->closure = closure;
   stringsink_init(&frame->sink);
-  
+
   return frame;
 }
 
@@ -955,7 +955,7 @@
                                   offsetof(map_parse_frame_data_t,
                                            key_storage));
   add_handlers_for_singular_field(h, value_field,
-                                  offsetof(map_parse_frame_data_t, 
+                                  offsetof(map_parse_frame_data_t,
                                            value_storage));
 }
 
diff --git a/php/ext/google/protobuf/message.c b/php/ext/google/protobuf/message.c
index 079bd1d..7cc3032 100644
--- a/php/ext/google/protobuf/message.c
+++ b/php/ext/google/protobuf/message.c
@@ -294,6 +294,57 @@
 // PHP Methods
 // -----------------------------------------------------------------------------
 
+static bool is_wrapper_msg(const upb_msgdef* m) {
+  upb_wellknowntype_t type = upb_msgdef_wellknowntype(m);
+  return type >= UPB_WELLKNOWN_DOUBLEVALUE &&
+         type <= UPB_WELLKNOWN_BOOLVALUE;
+}
+
+static void append_wrapper_message(
+    zend_class_entry* subklass, RepeatedField* intern, zval* value TSRMLS_DC) {
+  MessageHeader* submsg;
+  const upb_fielddef* field;
+#if PHP_MAJOR_VERSION < 7
+  zval* val = NULL;
+  MAKE_STD_ZVAL(val);
+  ZVAL_OBJ(val, subklass->create_object(subklass TSRMLS_CC));
+  repeated_field_push_native(intern, &val);
+  submsg = UNBOX(MessageHeader, val);
+#else
+  zend_object* obj = subklass->create_object(subklass TSRMLS_CC);
+  repeated_field_push_native(intern, &obj);
+  submsg = (MessageHeader*)((char*)obj - XtOffsetOf(MessageHeader, std));
+#endif
+  custom_data_init(subklass, submsg PHP_PROTO_TSRMLS_CC);
+
+  field = upb_msgdef_itof(submsg->descriptor->msgdef, 1);
+  layout_set(submsg->descriptor->layout, submsg, field, value TSRMLS_CC);
+}
+
+static void set_wrapper_message_as_map_value(
+    zend_class_entry* subklass, zval* map, zval* key,  zval* value TSRMLS_DC) {
+  MessageHeader* submsg;
+  const upb_fielddef* field;
+#if PHP_MAJOR_VERSION < 7
+  zval* val = NULL;
+  MAKE_STD_ZVAL(val);
+  ZVAL_OBJ(val, subklass->create_object(subklass TSRMLS_CC));
+  map_field_handlers->write_dimension(
+      map, key, val TSRMLS_CC);
+  submsg = UNBOX(MessageHeader, val);
+#else
+  zval val;
+  zend_object* obj = subklass->create_object(subklass TSRMLS_CC);
+  ZVAL_OBJ(&val, obj);
+  map_field_handlers->write_dimension(map, key, &val TSRMLS_CC);
+  submsg = (MessageHeader*)((char*)obj - XtOffsetOf(MessageHeader, std));
+#endif
+  custom_data_init(subklass, submsg PHP_PROTO_TSRMLS_CC);
+
+  field = upb_msgdef_itof(submsg->descriptor->msgdef, 1);
+  layout_set(submsg->descriptor->layout, submsg, field, value TSRMLS_CC);
+}
+
 void Message_construct(zval* msg, zval* array_wrapper) {
   TSRMLS_FETCH();
   zend_class_entry* ce = Z_OBJCE_P(msg);
@@ -336,14 +387,38 @@
       HashPosition subpointer;
       zval subkey;
       void* memory;
+      bool is_wrapper = false;
+      zend_class_entry* subklass = NULL;
+      const upb_msgdef* mapentry = upb_fielddef_msgsubdef(field);
+      const upb_fielddef *value_field = upb_msgdef_itof(mapentry, 2);
+
+      if (upb_fielddef_issubmsg(value_field)) {
+        const upb_msgdef* submsgdef = upb_fielddef_msgsubdef(value_field);
+        upb_wellknowntype_t type = upb_msgdef_wellknowntype(submsgdef);
+        is_wrapper = is_wrapper_msg(submsgdef);
+
+        if (is_wrapper) {
+          PHP_PROTO_HASHTABLE_VALUE subdesc_php = get_def_obj(submsgdef);
+          Descriptor* subdesc = UNBOX_HASHTABLE_VALUE(Descriptor, subdesc_php);
+          subklass = subdesc->klass;
+        }
+      }
+
       for (zend_hash_internal_pointer_reset_ex(subtable, &subpointer);
            php_proto_zend_hash_get_current_data_ex(subtable, (void**)&memory,
                                                    &subpointer) == SUCCESS;
            zend_hash_move_forward_ex(subtable, &subpointer)) {
         zend_hash_get_current_key_zval_ex(subtable, &subkey, &subpointer);
-        map_field_handlers->write_dimension(
-            submap, &subkey,
-            CACHED_PTR_TO_ZVAL_PTR((CACHED_VALUE*)memory) TSRMLS_CC);
+        if (is_wrapper &&
+            Z_TYPE_P(CACHED_PTR_TO_ZVAL_PTR((CACHED_VALUE*)memory)) != IS_OBJECT) {
+          set_wrapper_message_as_map_value(
+              subklass, submap, &subkey,
+              CACHED_PTR_TO_ZVAL_PTR((CACHED_VALUE*)memory) TSRMLS_CC);
+        } else {
+          map_field_handlers->write_dimension(
+              submap, &subkey,
+              CACHED_PTR_TO_ZVAL_PTR((CACHED_VALUE*)memory) TSRMLS_CC);
+        }
         zval_dtor(&subkey);
       }
     } else if (upb_fielddef_isseq(field)) {
@@ -354,13 +429,36 @@
           CACHED_PTR_TO_ZVAL_PTR((CACHED_VALUE*)value));
       HashPosition subpointer;
       void* memory;
+      bool is_wrapper = false;
+      zend_class_entry* subklass = NULL;
+
+      if (upb_fielddef_issubmsg(field)) {
+        const upb_msgdef* submsgdef = upb_fielddef_msgsubdef(field);
+        upb_wellknowntype_t type = upb_msgdef_wellknowntype(submsgdef);
+        is_wrapper = is_wrapper_msg(submsgdef);
+
+        if (is_wrapper) {
+          PHP_PROTO_HASHTABLE_VALUE subdesc_php = get_def_obj(submsgdef);
+          Descriptor* subdesc = UNBOX_HASHTABLE_VALUE(Descriptor, subdesc_php);
+          subklass = subdesc->klass;
+        }
+      }
+
       for (zend_hash_internal_pointer_reset_ex(subtable, &subpointer);
            php_proto_zend_hash_get_current_data_ex(subtable, (void**)&memory,
                                                    &subpointer) == SUCCESS;
            zend_hash_move_forward_ex(subtable, &subpointer)) {
-        repeated_field_handlers->write_dimension(
-            subarray, NULL,
-            CACHED_PTR_TO_ZVAL_PTR((CACHED_VALUE*)memory) TSRMLS_CC);
+        if (is_wrapper &&
+            Z_TYPE_P(CACHED_PTR_TO_ZVAL_PTR((CACHED_VALUE*)memory)) != IS_OBJECT) {
+          RepeatedField* intern = UNBOX(RepeatedField, subarray);
+          append_wrapper_message(
+              subklass, intern,
+              CACHED_PTR_TO_ZVAL_PTR((CACHED_VALUE*)memory) TSRMLS_CC);
+        } else {
+          repeated_field_handlers->write_dimension(
+              subarray, NULL,
+              CACHED_PTR_TO_ZVAL_PTR((CACHED_VALUE*)memory) TSRMLS_CC);
+        }
       }
     } else if (upb_fielddef_issubmsg(field)) {
       const upb_msgdef* submsgdef = upb_fielddef_msgsubdef(field);
diff --git a/php/ext/google/protobuf/type_check.c b/php/ext/google/protobuf/type_check.c
index d8a9245..e037e63 100644
--- a/php/ext/google/protobuf/type_check.c
+++ b/php/ext/google/protobuf/type_check.c
@@ -88,7 +88,7 @@
 // Type checking/conversion.
 // -----------------------------------------------------------------------------
 
-// This is modified from is_numeric_string in zend_operators.h. The behavior of 
+// This is modified from is_numeric_string in zend_operators.h. The behavior of
 // this function is the same as is_numeric_string, except that this takes
 // int64_t as input instead of long.
 static zend_uchar convert_numeric_string(
@@ -102,7 +102,7 @@
     return IS_NULL;
   }
 
-  while (*str == ' ' || *str == '\t' || *str == '\n' || 
+  while (*str == ' ' || *str == '\t' || *str == '\n' ||
          *str == '\r' || *str == '\v' || *str == '\f') {
     str++;
     length--;
diff --git a/php/ext/google/protobuf/upb.c b/php/ext/google/protobuf/upb.c
index 8452334..fb77234 100644
--- a/php/ext/google/protobuf/upb.c
+++ b/php/ext/google/protobuf/upb.c
@@ -13327,7 +13327,7 @@
   if (multipart_text(p, p->capture, *ptr - p->capture, false)) {
     /* We use this as a signal that we were in the middle of capturing, and
      * that capturing should resume at the beginning of the next buffer.
-     * 
+     *
      * We can't use *ptr here, because we have no guarantee that this pointer
      * will be valid when we resume (if the underlying memory is freed, then
      * using the pointer at all, even to compare to NULL, is likely undefined
@@ -13877,7 +13877,7 @@
     }
 
     json_parser_any_frame_set_payload_type(p, p->top->any_frame, payload_type);
-    
+
     return true;
   } else {
     upb_status_seterrf(
@@ -15134,242 +15134,242 @@
 
 #line 2556 "upb/json/parser.c"
 static const char _json_actions[] = {
-	0, 1, 0, 1, 1, 1, 3, 1, 
-	4, 1, 6, 1, 7, 1, 8, 1, 
-	9, 1, 10, 1, 11, 1, 12, 1, 
-	13, 1, 24, 1, 26, 1, 28, 1, 
-	29, 1, 31, 1, 32, 1, 33, 1, 
-	35, 1, 37, 1, 38, 1, 39, 1, 
-	40, 1, 42, 1, 43, 2, 4, 9, 
-	2, 5, 6, 2, 7, 3, 2, 7, 
-	9, 2, 14, 15, 2, 16, 17, 2, 
-	18, 19, 2, 21, 23, 2, 22, 20, 
-	2, 27, 25, 2, 29, 31, 2, 34, 
-	2, 2, 35, 43, 2, 36, 25, 2, 
-	38, 43, 2, 39, 43, 2, 40, 43, 
-	2, 41, 30, 2, 42, 43, 3, 21, 
+	0, 1, 0, 1, 1, 1, 3, 1,
+	4, 1, 6, 1, 7, 1, 8, 1,
+	9, 1, 10, 1, 11, 1, 12, 1,
+	13, 1, 24, 1, 26, 1, 28, 1,
+	29, 1, 31, 1, 32, 1, 33, 1,
+	35, 1, 37, 1, 38, 1, 39, 1,
+	40, 1, 42, 1, 43, 2, 4, 9,
+	2, 5, 6, 2, 7, 3, 2, 7,
+	9, 2, 14, 15, 2, 16, 17, 2,
+	18, 19, 2, 21, 23, 2, 22, 20,
+	2, 27, 25, 2, 29, 31, 2, 34,
+	2, 2, 35, 43, 2, 36, 25, 2,
+	38, 43, 2, 39, 43, 2, 40, 43,
+	2, 41, 30, 2, 42, 43, 3, 21,
 	23, 24, 4, 14, 15, 16, 17
 };
 
 static const short _json_key_offsets[] = {
-	0, 0, 12, 13, 18, 23, 28, 29, 
-	30, 31, 32, 33, 34, 35, 36, 37, 
-	38, 43, 44, 48, 53, 58, 63, 67, 
-	71, 74, 77, 79, 83, 87, 89, 91, 
-	96, 98, 100, 109, 115, 121, 127, 133, 
-	135, 139, 142, 144, 146, 149, 150, 154, 
-	156, 158, 160, 162, 163, 165, 167, 168, 
-	170, 172, 173, 175, 177, 178, 180, 182, 
-	183, 185, 187, 191, 193, 195, 196, 197, 
-	198, 199, 201, 206, 208, 210, 212, 221, 
-	222, 222, 222, 227, 232, 237, 238, 239, 
-	240, 241, 241, 242, 243, 244, 244, 245, 
-	246, 247, 247, 252, 253, 257, 262, 267, 
-	272, 276, 276, 279, 282, 285, 288, 291, 
+	0, 0, 12, 13, 18, 23, 28, 29,
+	30, 31, 32, 33, 34, 35, 36, 37,
+	38, 43, 44, 48, 53, 58, 63, 67,
+	71, 74, 77, 79, 83, 87, 89, 91,
+	96, 98, 100, 109, 115, 121, 127, 133,
+	135, 139, 142, 144, 146, 149, 150, 154,
+	156, 158, 160, 162, 163, 165, 167, 168,
+	170, 172, 173, 175, 177, 178, 180, 182,
+	183, 185, 187, 191, 193, 195, 196, 197,
+	198, 199, 201, 206, 208, 210, 212, 221,
+	222, 222, 222, 227, 232, 237, 238, 239,
+	240, 241, 241, 242, 243, 244, 244, 245,
+	246, 247, 247, 252, 253, 257, 262, 267,
+	272, 276, 276, 279, 282, 285, 288, 291,
 	294, 294, 294, 294, 294, 294
 };
 
 static const char _json_trans_keys[] = {
-	32, 34, 45, 91, 102, 110, 116, 123, 
-	9, 13, 48, 57, 34, 32, 93, 125, 
-	9, 13, 32, 44, 93, 9, 13, 32, 
-	93, 125, 9, 13, 97, 108, 115, 101, 
-	117, 108, 108, 114, 117, 101, 32, 34, 
-	125, 9, 13, 34, 32, 58, 9, 13, 
-	32, 93, 125, 9, 13, 32, 44, 125, 
-	9, 13, 32, 44, 125, 9, 13, 32, 
-	34, 9, 13, 45, 48, 49, 57, 48, 
-	49, 57, 46, 69, 101, 48, 57, 69, 
-	101, 48, 57, 43, 45, 48, 57, 48, 
-	57, 48, 57, 46, 69, 101, 48, 57, 
-	34, 92, 34, 92, 34, 47, 92, 98, 
-	102, 110, 114, 116, 117, 48, 57, 65, 
-	70, 97, 102, 48, 57, 65, 70, 97, 
-	102, 48, 57, 65, 70, 97, 102, 48, 
-	57, 65, 70, 97, 102, 34, 92, 45, 
-	48, 49, 57, 48, 49, 57, 46, 115, 
-	48, 57, 115, 48, 57, 34, 46, 115, 
-	48, 57, 48, 57, 48, 57, 48, 57, 
-	48, 57, 45, 48, 57, 48, 57, 45, 
-	48, 57, 48, 57, 84, 48, 57, 48, 
-	57, 58, 48, 57, 48, 57, 58, 48, 
-	57, 48, 57, 43, 45, 46, 90, 48, 
-	57, 48, 57, 58, 48, 48, 34, 48, 
-	57, 43, 45, 90, 48, 57, 34, 44, 
-	34, 44, 34, 44, 34, 45, 91, 102, 
-	110, 116, 123, 48, 57, 34, 32, 93, 
-	125, 9, 13, 32, 44, 93, 9, 13, 
-	32, 93, 125, 9, 13, 97, 108, 115, 
-	101, 117, 108, 108, 114, 117, 101, 32, 
-	34, 125, 9, 13, 34, 32, 58, 9, 
-	13, 32, 93, 125, 9, 13, 32, 44, 
-	125, 9, 13, 32, 44, 125, 9, 13, 
-	32, 34, 9, 13, 32, 9, 13, 32, 
-	9, 13, 32, 9, 13, 32, 9, 13, 
+	32, 34, 45, 91, 102, 110, 116, 123,
+	9, 13, 48, 57, 34, 32, 93, 125,
+	9, 13, 32, 44, 93, 9, 13, 32,
+	93, 125, 9, 13, 97, 108, 115, 101,
+	117, 108, 108, 114, 117, 101, 32, 34,
+	125, 9, 13, 34, 32, 58, 9, 13,
+	32, 93, 125, 9, 13, 32, 44, 125,
+	9, 13, 32, 44, 125, 9, 13, 32,
+	34, 9, 13, 45, 48, 49, 57, 48,
+	49, 57, 46, 69, 101, 48, 57, 69,
+	101, 48, 57, 43, 45, 48, 57, 48,
+	57, 48, 57, 46, 69, 101, 48, 57,
+	34, 92, 34, 92, 34, 47, 92, 98,
+	102, 110, 114, 116, 117, 48, 57, 65,
+	70, 97, 102, 48, 57, 65, 70, 97,
+	102, 48, 57, 65, 70, 97, 102, 48,
+	57, 65, 70, 97, 102, 34, 92, 45,
+	48, 49, 57, 48, 49, 57, 46, 115,
+	48, 57, 115, 48, 57, 34, 46, 115,
+	48, 57, 48, 57, 48, 57, 48, 57,
+	48, 57, 45, 48, 57, 48, 57, 45,
+	48, 57, 48, 57, 84, 48, 57, 48,
+	57, 58, 48, 57, 48, 57, 58, 48,
+	57, 48, 57, 43, 45, 46, 90, 48,
+	57, 48, 57, 58, 48, 48, 34, 48,
+	57, 43, 45, 90, 48, 57, 34, 44,
+	34, 44, 34, 44, 34, 45, 91, 102,
+	110, 116, 123, 48, 57, 34, 32, 93,
+	125, 9, 13, 32, 44, 93, 9, 13,
+	32, 93, 125, 9, 13, 97, 108, 115,
+	101, 117, 108, 108, 114, 117, 101, 32,
+	34, 125, 9, 13, 34, 32, 58, 9,
+	13, 32, 93, 125, 9, 13, 32, 44,
+	125, 9, 13, 32, 44, 125, 9, 13,
+	32, 34, 9, 13, 32, 9, 13, 32,
+	9, 13, 32, 9, 13, 32, 9, 13,
 	32, 9, 13, 32, 9, 13, 0
 };
 
 static const char _json_single_lengths[] = {
-	0, 8, 1, 3, 3, 3, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	3, 1, 2, 3, 3, 3, 2, 2, 
-	1, 3, 0, 2, 2, 0, 0, 3, 
-	2, 2, 9, 0, 0, 0, 0, 2, 
-	2, 1, 2, 0, 1, 1, 2, 0, 
-	0, 0, 0, 1, 0, 0, 1, 0, 
-	0, 1, 0, 0, 1, 0, 0, 1, 
-	0, 0, 4, 0, 0, 1, 1, 1, 
-	1, 0, 3, 2, 2, 2, 7, 1, 
-	0, 0, 3, 3, 3, 1, 1, 1, 
-	1, 0, 1, 1, 1, 0, 1, 1, 
-	1, 0, 3, 1, 2, 3, 3, 3, 
-	2, 0, 1, 1, 1, 1, 1, 1, 
+	0, 8, 1, 3, 3, 3, 1, 1,
+	1, 1, 1, 1, 1, 1, 1, 1,
+	3, 1, 2, 3, 3, 3, 2, 2,
+	1, 3, 0, 2, 2, 0, 0, 3,
+	2, 2, 9, 0, 0, 0, 0, 2,
+	2, 1, 2, 0, 1, 1, 2, 0,
+	0, 0, 0, 1, 0, 0, 1, 0,
+	0, 1, 0, 0, 1, 0, 0, 1,
+	0, 0, 4, 0, 0, 1, 1, 1,
+	1, 0, 3, 2, 2, 2, 7, 1,
+	0, 0, 3, 3, 3, 1, 1, 1,
+	1, 0, 1, 1, 1, 0, 1, 1,
+	1, 0, 3, 1, 2, 3, 3, 3,
+	2, 0, 1, 1, 1, 1, 1, 1,
 	0, 0, 0, 0, 0, 0
 };
 
 static const char _json_range_lengths[] = {
-	0, 2, 0, 1, 1, 1, 0, 0, 
-	0, 0, 0, 0, 0, 0, 0, 0, 
-	1, 0, 1, 1, 1, 1, 1, 1, 
-	1, 0, 1, 1, 1, 1, 1, 1, 
-	0, 0, 0, 3, 3, 3, 3, 0, 
-	1, 1, 0, 1, 1, 0, 1, 1, 
-	1, 1, 1, 0, 1, 1, 0, 1, 
-	1, 0, 1, 1, 0, 1, 1, 0, 
-	1, 1, 0, 1, 1, 0, 0, 0, 
-	0, 1, 1, 0, 0, 0, 1, 0, 
-	0, 0, 1, 1, 1, 0, 0, 0, 
-	0, 0, 0, 0, 0, 0, 0, 0, 
-	0, 0, 1, 0, 1, 1, 1, 1, 
-	1, 0, 1, 1, 1, 1, 1, 1, 
+	0, 2, 0, 1, 1, 1, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0,
+	1, 0, 1, 1, 1, 1, 1, 1,
+	1, 0, 1, 1, 1, 1, 1, 1,
+	0, 0, 0, 3, 3, 3, 3, 0,
+	1, 1, 0, 1, 1, 0, 1, 1,
+	1, 1, 1, 0, 1, 1, 0, 1,
+	1, 0, 1, 1, 0, 1, 1, 0,
+	1, 1, 0, 1, 1, 0, 0, 0,
+	0, 1, 1, 0, 0, 0, 1, 0,
+	0, 0, 1, 1, 1, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 1, 0, 1, 1, 1, 1,
+	1, 0, 1, 1, 1, 1, 1, 1,
 	0, 0, 0, 0, 0, 0
 };
 
 static const short _json_index_offsets[] = {
-	0, 0, 11, 13, 18, 23, 28, 30, 
-	32, 34, 36, 38, 40, 42, 44, 46, 
-	48, 53, 55, 59, 64, 69, 74, 78, 
-	82, 85, 89, 91, 95, 99, 101, 103, 
-	108, 111, 114, 124, 128, 132, 136, 140, 
-	143, 147, 150, 153, 155, 158, 160, 164, 
-	166, 168, 170, 172, 174, 176, 178, 180, 
-	182, 184, 186, 188, 190, 192, 194, 196, 
-	198, 200, 202, 207, 209, 211, 213, 215, 
-	217, 219, 221, 226, 229, 232, 235, 244, 
-	246, 247, 248, 253, 258, 263, 265, 267, 
-	269, 271, 272, 274, 276, 278, 279, 281, 
-	283, 285, 286, 291, 293, 297, 302, 307, 
-	312, 316, 317, 320, 323, 326, 329, 332, 
+	0, 0, 11, 13, 18, 23, 28, 30,
+	32, 34, 36, 38, 40, 42, 44, 46,
+	48, 53, 55, 59, 64, 69, 74, 78,
+	82, 85, 89, 91, 95, 99, 101, 103,
+	108, 111, 114, 124, 128, 132, 136, 140,
+	143, 147, 150, 153, 155, 158, 160, 164,
+	166, 168, 170, 172, 174, 176, 178, 180,
+	182, 184, 186, 188, 190, 192, 194, 196,
+	198, 200, 202, 207, 209, 211, 213, 215,
+	217, 219, 221, 226, 229, 232, 235, 244,
+	246, 247, 248, 253, 258, 263, 265, 267,
+	269, 271, 272, 274, 276, 278, 279, 281,
+	283, 285, 286, 291, 293, 297, 302, 307,
+	312, 316, 317, 320, 323, 326, 329, 332,
 	335, 336, 337, 338, 339, 340
 };
 
 static const unsigned char _json_indicies[] = {
-	0, 2, 3, 4, 5, 6, 7, 8, 
-	0, 3, 1, 9, 1, 11, 12, 1, 
-	11, 10, 13, 14, 12, 13, 1, 14, 
-	1, 1, 14, 10, 15, 1, 16, 1, 
-	17, 1, 18, 1, 19, 1, 20, 1, 
-	21, 1, 22, 1, 23, 1, 24, 1, 
-	25, 26, 27, 25, 1, 28, 1, 29, 
-	30, 29, 1, 30, 1, 1, 30, 31, 
-	32, 33, 34, 32, 1, 35, 36, 27, 
-	35, 1, 36, 26, 36, 1, 37, 38, 
-	39, 1, 38, 39, 1, 41, 42, 42, 
-	40, 43, 1, 42, 42, 43, 40, 44, 
-	44, 45, 1, 45, 1, 45, 40, 41, 
-	42, 42, 39, 40, 47, 48, 46, 50, 
-	51, 49, 52, 52, 52, 52, 52, 52, 
-	52, 52, 53, 1, 54, 54, 54, 1, 
-	55, 55, 55, 1, 56, 56, 56, 1, 
-	57, 57, 57, 1, 59, 60, 58, 61, 
-	62, 63, 1, 64, 65, 1, 66, 67, 
-	1, 68, 1, 67, 68, 1, 69, 1, 
-	66, 67, 65, 1, 70, 1, 71, 1, 
-	72, 1, 73, 1, 74, 1, 75, 1, 
-	76, 1, 77, 1, 78, 1, 79, 1, 
-	80, 1, 81, 1, 82, 1, 83, 1, 
-	84, 1, 85, 1, 86, 1, 87, 1, 
-	88, 1, 89, 89, 90, 91, 1, 92, 
-	1, 93, 1, 94, 1, 95, 1, 96, 
-	1, 97, 1, 98, 1, 99, 99, 100, 
-	98, 1, 102, 1, 101, 104, 105, 103, 
-	1, 1, 101, 106, 107, 108, 109, 110, 
-	111, 112, 107, 1, 113, 1, 114, 115, 
-	117, 118, 1, 117, 116, 119, 120, 118, 
-	119, 1, 120, 1, 1, 120, 116, 121, 
-	1, 122, 1, 123, 1, 124, 1, 125, 
-	126, 1, 127, 1, 128, 1, 129, 130, 
-	1, 131, 1, 132, 1, 133, 134, 135, 
-	136, 134, 1, 137, 1, 138, 139, 138, 
-	1, 139, 1, 1, 139, 140, 141, 142, 
-	143, 141, 1, 144, 145, 136, 144, 1, 
-	145, 135, 145, 1, 146, 147, 147, 1, 
-	148, 148, 1, 149, 149, 1, 150, 150, 
-	1, 151, 151, 1, 152, 152, 1, 1, 
+	0, 2, 3, 4, 5, 6, 7, 8,
+	0, 3, 1, 9, 1, 11, 12, 1,
+	11, 10, 13, 14, 12, 13, 1, 14,
+	1, 1, 14, 10, 15, 1, 16, 1,
+	17, 1, 18, 1, 19, 1, 20, 1,
+	21, 1, 22, 1, 23, 1, 24, 1,
+	25, 26, 27, 25, 1, 28, 1, 29,
+	30, 29, 1, 30, 1, 1, 30, 31,
+	32, 33, 34, 32, 1, 35, 36, 27,
+	35, 1, 36, 26, 36, 1, 37, 38,
+	39, 1, 38, 39, 1, 41, 42, 42,
+	40, 43, 1, 42, 42, 43, 40, 44,
+	44, 45, 1, 45, 1, 45, 40, 41,
+	42, 42, 39, 40, 47, 48, 46, 50,
+	51, 49, 52, 52, 52, 52, 52, 52,
+	52, 52, 53, 1, 54, 54, 54, 1,
+	55, 55, 55, 1, 56, 56, 56, 1,
+	57, 57, 57, 1, 59, 60, 58, 61,
+	62, 63, 1, 64, 65, 1, 66, 67,
+	1, 68, 1, 67, 68, 1, 69, 1,
+	66, 67, 65, 1, 70, 1, 71, 1,
+	72, 1, 73, 1, 74, 1, 75, 1,
+	76, 1, 77, 1, 78, 1, 79, 1,
+	80, 1, 81, 1, 82, 1, 83, 1,
+	84, 1, 85, 1, 86, 1, 87, 1,
+	88, 1, 89, 89, 90, 91, 1, 92,
+	1, 93, 1, 94, 1, 95, 1, 96,
+	1, 97, 1, 98, 1, 99, 99, 100,
+	98, 1, 102, 1, 101, 104, 105, 103,
+	1, 1, 101, 106, 107, 108, 109, 110,
+	111, 112, 107, 1, 113, 1, 114, 115,
+	117, 118, 1, 117, 116, 119, 120, 118,
+	119, 1, 120, 1, 1, 120, 116, 121,
+	1, 122, 1, 123, 1, 124, 1, 125,
+	126, 1, 127, 1, 128, 1, 129, 130,
+	1, 131, 1, 132, 1, 133, 134, 135,
+	136, 134, 1, 137, 1, 138, 139, 138,
+	1, 139, 1, 1, 139, 140, 141, 142,
+	143, 141, 1, 144, 145, 136, 144, 1,
+	145, 135, 145, 1, 146, 147, 147, 1,
+	148, 148, 1, 149, 149, 1, 150, 150,
+	1, 151, 151, 1, 152, 152, 1, 1,
 	1, 1, 1, 1, 1, 0
 };
 
 static const char _json_trans_targs[] = {
-	1, 0, 2, 107, 3, 6, 10, 13, 
-	16, 106, 4, 3, 106, 4, 5, 7, 
-	8, 9, 108, 11, 12, 109, 14, 15, 
-	110, 16, 17, 111, 18, 18, 19, 20, 
-	21, 22, 111, 21, 22, 24, 25, 31, 
-	112, 26, 28, 27, 29, 30, 33, 113, 
-	34, 33, 113, 34, 32, 35, 36, 37, 
-	38, 39, 33, 113, 34, 41, 42, 46, 
-	42, 46, 43, 45, 44, 114, 48, 49, 
-	50, 51, 52, 53, 54, 55, 56, 57, 
-	58, 59, 60, 61, 62, 63, 64, 65, 
-	66, 67, 73, 72, 68, 69, 70, 71, 
-	72, 115, 74, 67, 72, 76, 116, 76, 
-	116, 77, 79, 81, 82, 85, 90, 94, 
-	98, 80, 117, 117, 83, 82, 80, 83, 
-	84, 86, 87, 88, 89, 117, 91, 92, 
-	93, 117, 95, 96, 97, 117, 98, 99, 
-	105, 100, 100, 101, 102, 103, 104, 105, 
-	103, 104, 117, 106, 106, 106, 106, 106, 
+	1, 0, 2, 107, 3, 6, 10, 13,
+	16, 106, 4, 3, 106, 4, 5, 7,
+	8, 9, 108, 11, 12, 109, 14, 15,
+	110, 16, 17, 111, 18, 18, 19, 20,
+	21, 22, 111, 21, 22, 24, 25, 31,
+	112, 26, 28, 27, 29, 30, 33, 113,
+	34, 33, 113, 34, 32, 35, 36, 37,
+	38, 39, 33, 113, 34, 41, 42, 46,
+	42, 46, 43, 45, 44, 114, 48, 49,
+	50, 51, 52, 53, 54, 55, 56, 57,
+	58, 59, 60, 61, 62, 63, 64, 65,
+	66, 67, 73, 72, 68, 69, 70, 71,
+	72, 115, 74, 67, 72, 76, 116, 76,
+	116, 77, 79, 81, 82, 85, 90, 94,
+	98, 80, 117, 117, 83, 82, 80, 83,
+	84, 86, 87, 88, 89, 117, 91, 92,
+	93, 117, 95, 96, 97, 117, 98, 99,
+	105, 100, 100, 101, 102, 103, 104, 105,
+	103, 104, 117, 106, 106, 106, 106, 106,
 	106
 };
 
 static const char _json_trans_actions[] = {
-	0, 0, 92, 86, 35, 0, 0, 0, 
-	104, 41, 27, 0, 37, 0, 0, 0, 
-	0, 0, 0, 0, 0, 0, 0, 0, 
-	0, 0, 80, 33, 29, 0, 0, 27, 
-	31, 31, 83, 0, 0, 0, 0, 0, 
-	3, 0, 0, 0, 0, 0, 5, 15, 
-	0, 0, 53, 7, 13, 0, 56, 9, 
-	9, 9, 59, 62, 11, 17, 17, 17, 
-	0, 0, 0, 19, 0, 21, 23, 0, 
-	0, 0, 0, 0, 0, 0, 0, 0, 
-	0, 0, 0, 0, 0, 0, 0, 0, 
-	0, 114, 65, 114, 0, 0, 0, 0, 
-	0, 71, 0, 68, 68, 77, 25, 0, 
-	110, 74, 92, 86, 35, 0, 0, 0, 
-	104, 41, 51, 89, 27, 0, 37, 0, 
-	0, 0, 0, 0, 0, 98, 0, 0, 
-	0, 101, 0, 0, 0, 95, 0, 80, 
-	33, 29, 0, 0, 27, 31, 31, 83, 
-	0, 0, 107, 0, 39, 45, 47, 43, 
+	0, 0, 92, 86, 35, 0, 0, 0,
+	104, 41, 27, 0, 37, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 80, 33, 29, 0, 0, 27,
+	31, 31, 83, 0, 0, 0, 0, 0,
+	3, 0, 0, 0, 0, 0, 5, 15,
+	0, 0, 53, 7, 13, 0, 56, 9,
+	9, 9, 59, 62, 11, 17, 17, 17,
+	0, 0, 0, 19, 0, 21, 23, 0,
+	0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0,
+	0, 114, 65, 114, 0, 0, 0, 0,
+	0, 71, 0, 68, 68, 77, 25, 0,
+	110, 74, 92, 86, 35, 0, 0, 0,
+	104, 41, 51, 89, 27, 0, 37, 0,
+	0, 0, 0, 0, 0, 98, 0, 0,
+	0, 101, 0, 0, 0, 95, 0, 80,
+	33, 29, 0, 0, 27, 31, 31, 83,
+	0, 0, 107, 0, 39, 45, 47, 43,
 	49
 };
 
 static const char _json_eof_actions[] = {
-	0, 0, 0, 0, 0, 0, 0, 0, 
-	0, 0, 0, 0, 0, 0, 0, 0, 
-	0, 0, 0, 0, 0, 0, 0, 0, 
-	0, 1, 0, 1, 0, 0, 1, 1, 
-	0, 0, 0, 0, 0, 0, 0, 0, 
-	0, 0, 0, 0, 0, 0, 0, 0, 
-	0, 0, 0, 0, 0, 0, 0, 0, 
-	0, 0, 0, 0, 0, 0, 0, 0, 
-	0, 0, 0, 0, 0, 0, 0, 0, 
-	0, 0, 0, 0, 0, 0, 0, 0, 
-	0, 0, 0, 0, 0, 0, 0, 0, 
-	0, 0, 0, 0, 0, 0, 0, 0, 
-	0, 0, 0, 0, 0, 0, 0, 0, 
-	0, 0, 0, 39, 45, 47, 43, 49, 
+	0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0,
+	0, 1, 0, 1, 0, 0, 1, 1,
+	0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 39, 45, 47, 43, 49,
 	0, 0, 0, 0, 0, 0
 };
 
@@ -15406,7 +15406,7 @@
 
   capture_resume(parser, buf);
 
-  
+
 #line 2831 "upb/json/parser.c"
 	{
 	int _klen;
@@ -15785,7 +15785,7 @@
   p->top->is_unknown_field = false;
 
   /* Emit Ragel initialization of the parser. */
-  
+
 #line 3210 "upb/json/parser.c"
 	{
 	cs = json_start;
diff --git a/php/ext/google/protobuf/upb.h b/php/ext/google/protobuf/upb.h
index 86393c6..b6a2058 100644
--- a/php/ext/google/protobuf/upb.h
+++ b/php/ext/google/protobuf/upb.h
@@ -5042,7 +5042,7 @@
 
 /* BoundFunc2, BoundFunc3: Like Func2/Func3 except also contains a value that
  * shall be bound to the function's second parameter.
- * 
+ *
  * Note that the second parameter is a const pointer, but our stored bound value
  * is non-const so we can free it when the handlers are destroyed. */
 template <class T>
diff --git a/php/src/Google/Protobuf/Internal/GPBWire.php b/php/src/Google/Protobuf/Internal/GPBWire.php
index e7eec55..7f1eab3 100644
--- a/php/src/Google/Protobuf/Internal/GPBWire.php
+++ b/php/src/Google/Protobuf/Internal/GPBWire.php
@@ -446,7 +446,7 @@
             if (bccomp($value, 0) < 0 ||
                 bccomp($value, "9223372036854775807") > 0) {
                 return 10;
-            }    
+            }
             if (bccomp($value, 1 << 7) < 0) {
                 return 1;
             }
@@ -475,7 +475,7 @@
         } else {
             if ($value < 0) {
                 return 10;
-            }    
+            }
             if ($value < (1 <<  7)) {
                 return 1;
             }
diff --git a/php/src/Google/Protobuf/Internal/Message.php b/php/src/Google/Protobuf/Internal/Message.php
index d304a12..9765e09 100644
--- a/php/src/Google/Protobuf/Internal/Message.php
+++ b/php/src/Google/Protobuf/Internal/Message.php
@@ -973,9 +973,12 @@
      * ]);
      * ```
      *
+     * This method will trigger an error if it is passed data that cannot
+     * be converted to the correct type. For example, a StringValue field
+     * must receive data that is either a string or a StringValue object.
+     *
      * @param array $array An array containing message properties and values.
      * @return null.
-     * @throws \Exception Invalid data.
      */
     protected function mergeFromArray(array $array)
     {
@@ -987,22 +990,61 @@
                     'Invalid message property: ' . $key);
             }
             $setter = $field->getSetter();
-            if ($field->isWrapperType()) {
-                self::normalizeToMessageType($value, $field->getMessageType()->getClass());
+            if ($field->isMap()) {
+                $valueField = $field->getMessageType()->getFieldByName('value');
+                if (!is_null($valueField) && $valueField->isWrapperType()) {
+                    self::normalizeArrayElementsToMessageType($value, $valueField->getMessageType()->getClass());
+                }
+            } elseif ($field->isWrapperType()) {
+                $class = $field->getMessageType()->getClass();
+                if ($field->isRepeated()) {
+                    self::normalizeArrayElementsToMessageType($value, $class);
+                } else {
+                    self::normalizeToMessageType($value, $class);
+                }
             }
             $this->$setter($value);
         }
     }
 
     /**
+     * Tries to normalize the elements in $value into a provided protobuf
+     * wrapper type $class. If $value is any type other than array, we do
+     * not do any conversion, and instead rely on the existing protobuf
+     * type checking. If $value is an array, we process each element and
+     * try to convert it to an instance of $class.
+     *
+     * @param mixed $value The array of values to normalize.
+     * @param string $class The expected wrapper class name
+     */
+    private static function normalizeArrayElementsToMessageType(&$value, $class)
+    {
+        if (!is_array($value)) {
+            // In the case that $value is not an array, we do not want to
+            // attempt any conversion. Note that this includes the cases
+            // when $value is a RepeatedField of MapField. In those cases,
+            // we do not need to convert the elements, as they should
+            // already be the correct types.
+            return;
+        } else {
+            // Normalize each element in the array.
+            foreach ($value as $key => &$elementValue) {
+              self::normalizeToMessageType($elementValue, $class);
+            }
+        }
+    }
+
+    /**
      * Tries to normalize $value into a provided protobuf wrapper type $class.
      * If $value is any type other than an object, we attempt to construct an
      * instance of $class and assign $value to it using the setValue method
      * shared by all wrapper types.
      *
+     * This method will raise an error if it receives a type that cannot be
+     * assigned to the wrapper type via setValue.
+     *
      * @param mixed $value The value to normalize.
      * @param string $class The expected wrapper class name
-     * @throws \Exception If $value cannot be converted to a wrapper type
      */
     private static function normalizeToMessageType(&$value, $class)
     {
@@ -1019,10 +1061,9 @@
                 $value = $msg;
                 return;
             } catch (\Exception $exception) {
-                throw new \Exception(
+                trigger_error(
                     "Error normalizing value to type '$class': " . $exception->getMessage(),
-                    $exception->getCode(),
-                    $exception
+                    E_USER_ERROR
                 );
             }
         }
diff --git a/php/tests/proto/test_wrapper_type_setters.proto b/php/tests/proto/test_wrapper_type_setters.proto
index e1e3309..41ca7f3 100644
--- a/php/tests/proto/test_wrapper_type_setters.proto
+++ b/php/tests/proto/test_wrapper_type_setters.proto
@@ -19,4 +19,8 @@
     google.protobuf.DoubleValue double_value_oneof = 10;
     google.protobuf.StringValue string_value_oneof = 11;
   }
+
+  repeated google.protobuf.StringValue repeated_string_value = 12;
+
+  map<string, google.protobuf.StringValue> map_string_value = 13;
 }
diff --git a/php/tests/wrapper_type_setters_test.php b/php/tests/wrapper_type_setters_test.php
index 3d09c9a..5509a17 100644
--- a/php/tests/wrapper_type_setters_test.php
+++ b/php/tests/wrapper_type_setters_test.php
@@ -225,4 +225,88 @@
             [TestWrapperSetters::class, BytesValue::class, 'bytes_value', 'getBytesValue', "nine"],
         ];
     }
+
+    /**
+     * @dataProvider constructorWithRepeatedWrapperTypeDataProvider
+     */
+    public function testConstructorWithRepeatedWrapperType($wrapperField, $getter, $value)
+    {
+        $actualInstance = new TestWrapperSetters([$wrapperField => $value]);
+        foreach ($actualInstance->$getter() as $key => $actualWrapperValue) {
+            $actualInnerValue = $actualWrapperValue->getValue();
+            $expectedElement = $value[$key];
+            if (is_object($expectedElement) && is_a($expectedElement, '\Google\Protobuf\StringValue')) {
+                $expectedInnerValue = $expectedElement->getValue();
+            } else {
+                $expectedInnerValue = $expectedElement;
+            }
+            $this->assertEquals($expectedInnerValue, $actualInnerValue);
+        }
+    }
+
+    public function constructorWithRepeatedWrapperTypeDataProvider()
+    {
+        $sv7 = new StringValue(['value' => 'seven']);
+        $sv8 = new StringValue(['value' => 'eight']);
+
+        $testWrapperSetters = new TestWrapperSetters();
+        $testWrapperSetters->setRepeatedStringValue([$sv7, $sv8]);
+        $repeatedField = $testWrapperSetters->getRepeatedStringValue();
+
+        return [
+            ['repeated_string_value', 'getRepeatedStringValue', []],
+            ['repeated_string_value', 'getRepeatedStringValue', [$sv7]],
+            ['repeated_string_value', 'getRepeatedStringValue', [$sv7, $sv8]],
+            ['repeated_string_value', 'getRepeatedStringValue', ['seven']],
+            ['repeated_string_value', 'getRepeatedStringValue', [7]],
+            ['repeated_string_value', 'getRepeatedStringValue', [7.7]],
+            ['repeated_string_value', 'getRepeatedStringValue', ['seven', 'eight']],
+            ['repeated_string_value', 'getRepeatedStringValue', [$sv7, 'eight']],
+            ['repeated_string_value', 'getRepeatedStringValue', ['seven', $sv8]],
+            ['repeated_string_value', 'getRepeatedStringValue', $repeatedField],
+        ];
+    }
+
+    /**
+     * @dataProvider constructorWithMapWrapperTypeDataProvider
+     */
+    public function testConstructorWithMapWrapperType($wrapperField, $getter, $value)
+    {
+        $actualInstance = new TestWrapperSetters([$wrapperField => $value]);
+        foreach ($actualInstance->$getter() as $key => $actualWrapperValue) {
+            $actualInnerValue = $actualWrapperValue->getValue();
+            $expectedElement = $value[$key];
+            if (is_object($expectedElement) && is_a($expectedElement, '\Google\Protobuf\StringValue')) {
+                $expectedInnerValue = $expectedElement->getValue();
+            } elseif (is_object($expectedElement) && is_a($expectedElement, '\Google\Protobuf\Internal\MapEntry')) {
+                $expectedInnerValue = $expectedElement->getValue()->getValue();
+            } else {
+                $expectedInnerValue = $expectedElement;
+            }
+            $this->assertEquals($expectedInnerValue, $actualInnerValue);
+        }
+    }
+
+    public function constructorWithMapWrapperTypeDataProvider()
+    {
+        $sv7 = new StringValue(['value' => 'seven']);
+        $sv8 = new StringValue(['value' => 'eight']);
+
+        $testWrapperSetters = new TestWrapperSetters();
+        $testWrapperSetters->setMapStringValue(['key' => $sv7, 'key2' => $sv8]);
+        $mapField = $testWrapperSetters->getMapStringValue();
+
+        return [
+            ['map_string_value', 'getMapStringValue', []],
+            ['map_string_value', 'getMapStringValue', ['key' => $sv7]],
+            ['map_string_value', 'getMapStringValue', ['key' => $sv7, 'key2' => $sv8]],
+            ['map_string_value', 'getMapStringValue', ['key' => 'seven']],
+            ['map_string_value', 'getMapStringValue', ['key' => 7]],
+            ['map_string_value', 'getMapStringValue', ['key' => 7.7]],
+            ['map_string_value', 'getMapStringValue', ['key' => 'seven', 'key2' => 'eight']],
+            ['map_string_value', 'getMapStringValue', ['key' => $sv7, 'key2' => 'eight']],
+            ['map_string_value', 'getMapStringValue', ['key' => 'seven', 'key2' => $sv8]],
+            ['map_string_value', 'getMapStringValue', $mapField],
+        ];
+    }
 }
diff --git a/protobuf-lite.pc.in b/protobuf-lite.pc.in
index 80f1f46..68a2bb4 100644
--- a/protobuf-lite.pc.in
+++ b/protobuf-lite.pc.in
@@ -6,6 +6,6 @@
 Name: Protocol Buffers
 Description: Google's Data Interchange Format
 Version: @VERSION@
-Libs: -L${libdir} -lprotobuf-lite @PTHREAD_CFLAGS@ @PTHREAD_LIBS@
+Libs: -L${libdir} -lprotobuf-lite @PTHREAD_LIBS@
 Cflags: -I${includedir} @PTHREAD_CFLAGS@
 Conflicts: protobuf
diff --git a/protobuf.pc.in b/protobuf.pc.in
index 4901490..282fef3 100644
--- a/protobuf.pc.in
+++ b/protobuf.pc.in
@@ -6,7 +6,7 @@
 Name: Protocol Buffers
 Description: Google's Data Interchange Format
 Version: @VERSION@
-Libs: -L${libdir} -lprotobuf @PTHREAD_CFLAGS@ @PTHREAD_LIBS@
+Libs: -L${libdir} -lprotobuf @PTHREAD_LIBS@
 Libs.private: @LIBS@
-Cflags: -I${includedir} @PTHREAD_CFLAGS@
+Cflags: -I${includedir} @PTHREAD_CFLAGS@ @CXXFLAGS@
 Conflicts: protobuf-lite
diff --git a/python/compatibility_tests/v2.5.0/tests/google/protobuf/internal/service_reflection_test.py b/python/compatibility_tests/v2.5.0/tests/google/protobuf/internal/service_reflection_test.py
index e04f825..2f0708d 100755
--- a/python/compatibility_tests/v2.5.0/tests/google/protobuf/internal/service_reflection_test.py
+++ b/python/compatibility_tests/v2.5.0/tests/google/protobuf/internal/service_reflection_test.py
@@ -80,7 +80,7 @@
     self.assertEqual('Method Bar not implemented.',
                      rpc_controller.failure_message)
     self.assertEqual(None, self.callback_response)
-    
+
     class MyServiceImpl(unittest_pb2.TestService):
       def Foo(self, rpc_controller, request, done):
         self.foo_called = True
diff --git a/python/google/protobuf/internal/_parameterized.py b/python/google/protobuf/internal/_parameterized.py
index f2c0b30..ca0bfec 100755
--- a/python/google/protobuf/internal/_parameterized.py
+++ b/python/google/protobuf/internal/_parameterized.py
@@ -263,7 +263,7 @@
       'Cannot add parameters to %s,'
       ' which already has parameterized methods.' % (class_object,))
   class_object._id_suffix = id_suffix = {}
-  # We change the size of __dict__ while we iterate over it, 
+  # We change the size of __dict__ while we iterate over it,
   # which Python 3.x will complain about, so use copy().
   for name, obj in class_object.__dict__.copy().items():
     if (name.startswith(unittest.TestLoader.testMethodPrefix)
diff --git a/python/tox.ini b/python/tox.ini
index 4eb319d..999f8ce 100644
--- a/python/tox.ini
+++ b/python/tox.ini
@@ -4,7 +4,7 @@
 
 [testenv]
 usedevelop=true
-passenv = 
+passenv =
     CC KOKORO_BUILD_ID KOKORO_BUILD_NUMBER
 setenv =
     cpp: LD_LIBRARY_PATH={toxinidir}/../src/.libs
diff --git a/ruby/README.md b/ruby/README.md
index 51299df..42a1ffa 100644
--- a/ruby/README.md
+++ b/ruby/README.md
@@ -12,7 +12,7 @@
 In Gemfile (Please check a version of Protocol Buffers you needed [RubyGems](https://rubygems.org/gems/google-protobuf)):
 
     gem 'google-protobuf'
- 
+
 Or for using this pre-packaged gem, simply install it as you would any other gem:
 
     $ gem install [--prerelease] google-protobuf
diff --git a/ruby/ext/google/protobuf_c/defs.c b/ruby/ext/google/protobuf_c/defs.c
index 6468a23..49c2ba6 100644
--- a/ruby/ext/google/protobuf_c/defs.c
+++ b/ruby/ext/google/protobuf_c/defs.c
@@ -886,7 +886,7 @@
   upb_fielddef* mut_def = check_field_notfrozen(self->fielddef);
 
   switch (upb_fielddef_type(mut_def)) {
-    case UPB_TYPE_FLOAT: 
+    case UPB_TYPE_FLOAT:
       upb_fielddef_setdefaultfloat(mut_def, NUM2DBL(default_value));
       break;
     case UPB_TYPE_DOUBLE:
@@ -902,16 +902,16 @@
       upb_fielddef_setdefaultbool(mut_def, RTEST(default_value));
       break;
     case UPB_TYPE_ENUM:
-    case UPB_TYPE_INT32: 
+    case UPB_TYPE_INT32:
       upb_fielddef_setdefaultint32(mut_def, NUM2INT(default_value));
       break;
-    case UPB_TYPE_INT64: 
+    case UPB_TYPE_INT64:
       upb_fielddef_setdefaultint64(mut_def, NUM2INT(default_value));
       break;
-    case UPB_TYPE_UINT32: 
+    case UPB_TYPE_UINT32:
       upb_fielddef_setdefaultuint32(mut_def, NUM2UINT(default_value));
       break;
-    case UPB_TYPE_UINT64: 
+    case UPB_TYPE_UINT64:
       upb_fielddef_setdefaultuint64(mut_def, NUM2UINT(default_value));
       break;
     case UPB_TYPE_STRING:
@@ -2085,7 +2085,7 @@
 
 void Builder_register(VALUE module) {
   VALUE klass = rb_define_class_under(module, "Builder", rb_cObject);
-  rb_define_alloc_func(klass, Builder_alloc); 
+  rb_define_alloc_func(klass, Builder_alloc);
   rb_define_method(klass, "initialize", Builder_initialize, 0);
   rb_define_method(klass, "add_file", Builder_add_file, -1);
   rb_define_method(klass, "add_message", Builder_add_message, 1);
@@ -2230,7 +2230,7 @@
     VALUE def_rb = rb_ary_entry(self->pending_list, i);
     if (CLASS_OF(def_rb) == cDescriptor) {
       self->defs[i] = (upb_def*)ruby_to_Descriptor(def_rb)->msgdef;
-      
+
       if (upb_filedef_syntax(upb_def_file(self->defs[i])) == UPB_SYNTAX_PROTO3) {
         proto3_validate_msgdef((const upb_msgdef*)self->defs[i]);
       }
diff --git a/ruby/ext/google/protobuf_c/map.c b/ruby/ext/google/protobuf_c/map.c
index 8c2f642..59d64fc 100644
--- a/ruby/ext/google/protobuf_c/map.c
+++ b/ruby/ext/google/protobuf_c/map.c
@@ -82,7 +82,7 @@
     case UPB_TYPE_INT64:
     case UPB_TYPE_UINT32:
     case UPB_TYPE_UINT64:
-      native_slot_set(self->key_type, Qnil, buf, key);
+      native_slot_set("", self->key_type, Qnil, buf, key);
       *out_key = buf;
       *out_length = native_slot_size(self->key_type);
       break;
@@ -396,7 +396,7 @@
   key = table_key(self, key, keybuf, &keyval, &length);
 
   mem = value_memory(&v);
-  native_slot_set(self->value_type, self->value_type_class, mem, value);
+  native_slot_set("", self->value_type, self->value_type_class, mem, value);
 
   // Replace any existing value by issuing a 'remove' operation first.
   upb_strtable_remove2(&self->table, keyval, length, NULL);
diff --git a/ruby/ext/google/protobuf_c/message.c b/ruby/ext/google/protobuf_c/message.c
index fd123ae..5a6a6bc 100644
--- a/ruby/ext/google/protobuf_c/message.c
+++ b/ruby/ext/google/protobuf_c/message.c
@@ -315,7 +315,8 @@
 
     if (TYPE(val) != T_HASH) {
       rb_raise(rb_eArgError,
-               "Expected Hash object as initializer value for map field '%s'.", name);
+               "Expected Hash object as initializer value for map field '%s' (given %s).",
+               name, rb_class2name(CLASS_OF(val)));
     }
     map = layout_get(self->descriptor->layout, Message_data(self), f);
     Map_merge_into_self(map, val);
@@ -324,7 +325,8 @@
 
     if (TYPE(val) != T_ARRAY) {
       rb_raise(rb_eArgError,
-               "Expected array as initializer value for repeated field '%s'.", name);
+               "Expected array as initializer value for repeated field '%s' (given %s).",
+               name, rb_class2name(CLASS_OF(val)));
     }
     ary = layout_get(self->descriptor->layout, Message_data(self), f);
     for (int i = 0; i < RARRAY_LEN(val); i++) {
@@ -620,10 +622,12 @@
   // Also define #clone so that we don't inherit Object#clone.
   rb_define_method(klass, "clone", Message_dup, 0);
   rb_define_method(klass, "==", Message_eq, 1);
+  rb_define_method(klass, "eql?", Message_eq, 1);
   rb_define_method(klass, "hash", Message_hash, 0);
   rb_define_method(klass, "to_h", Message_to_h, 0);
   rb_define_method(klass, "to_hash", Message_to_h, 0);
   rb_define_method(klass, "inspect", Message_inspect, 0);
+  rb_define_method(klass, "to_s", Message_inspect, 0);
   rb_define_method(klass, "[]", Message_index, 1);
   rb_define_method(klass, "[]=", Message_index_set, 2);
   rb_define_singleton_method(klass, "decode", Message_decode, 1);
diff --git a/ruby/ext/google/protobuf_c/protobuf.h b/ruby/ext/google/protobuf_c/protobuf.h
index eff212e..8731eeb 100644
--- a/ruby/ext/google/protobuf_c/protobuf.h
+++ b/ruby/ext/google/protobuf_c/protobuf.h
@@ -337,14 +337,16 @@
 #define NATIVE_SLOT_MAX_SIZE sizeof(uint64_t)
 
 size_t native_slot_size(upb_fieldtype_t type);
-void native_slot_set(upb_fieldtype_t type,
+void native_slot_set(const char* name,
+                     upb_fieldtype_t type,
                      VALUE type_class,
                      void* memory,
                      VALUE value);
 // Atomically (with respect to Ruby VM calls) either update the value and set a
 // oneof case, or do neither. If |case_memory| is null, then no case value is
 // set.
-void native_slot_set_value_and_case(upb_fieldtype_t type,
+void native_slot_set_value_and_case(const char* name,
+                                    upb_fieldtype_t type,
                                     VALUE type_class,
                                     void* memory,
                                     VALUE value,
@@ -360,7 +362,7 @@
 bool native_slot_eq(upb_fieldtype_t type, void* mem1, void* mem2);
 
 VALUE native_slot_encode_and_freeze_string(upb_fieldtype_t type, VALUE value);
-void native_slot_check_int_range_precision(upb_fieldtype_t type, VALUE value);
+void native_slot_check_int_range_precision(const char* name, upb_fieldtype_t type, VALUE value);
 
 extern rb_encoding* kRubyStringUtf8Encoding;
 extern rb_encoding* kRubyStringASCIIEncoding;
diff --git a/ruby/ext/google/protobuf_c/repeated_field.c b/ruby/ext/google/protobuf_c/repeated_field.c
index c6620ee..8f4c421 100644
--- a/ruby/ext/google/protobuf_c/repeated_field.c
+++ b/ruby/ext/google/protobuf_c/repeated_field.c
@@ -178,7 +178,7 @@
   }
 
   memory = RepeatedField_memoryat(self, index, element_size);
-  native_slot_set(field_type, field_type_class, memory, val);
+  native_slot_set("", field_type, field_type_class, memory, val);
   return Qnil;
 }
 
@@ -217,7 +217,7 @@
 
   RepeatedField_reserve(self, self->size + 1);
   memory = (void *) (((uint8_t *)self->elements) + self->size * element_size);
-  native_slot_set(field_type, self->field_type_class, memory, val);
+  native_slot_set("", field_type, self->field_type_class, memory, val);
   // native_slot_set may raise an error; bump size only after set.
   self->size++;
   return _self;
diff --git a/ruby/ext/google/protobuf_c/storage.c b/ruby/ext/google/protobuf_c/storage.c
index 6cf4158..e9fea23 100644
--- a/ruby/ext/google/protobuf_c/storage.c
+++ b/ruby/ext/google/protobuf_c/storage.c
@@ -65,9 +65,10 @@
           TYPE(value) == T_BIGNUM);
 }
 
-void native_slot_check_int_range_precision(upb_fieldtype_t type, VALUE val) {
+void native_slot_check_int_range_precision(const char* name, upb_fieldtype_t type, VALUE val) {
   if (!is_ruby_num(val)) {
-    rb_raise(cTypeError, "Expected number type for integral field.");
+    rb_raise(cTypeError, "Expected number type for integral field '%s' (given %s).",
+             name, rb_class2name(CLASS_OF(val)));
   }
 
   // NUM2{INT,UINT,LL,ULL} macros do the appropriate range checks on upper
@@ -77,13 +78,15 @@
     double dbl_val = NUM2DBL(val);
     if (floor(dbl_val) != dbl_val) {
       rb_raise(rb_eRangeError,
-               "Non-integral floating point value assigned to integer field.");
+               "Non-integral floating point value assigned to integer field '%s' (given %s).",
+               name, rb_class2name(CLASS_OF(val)));
     }
   }
   if (type == UPB_TYPE_UINT32 || type == UPB_TYPE_UINT64) {
     if (NUM2DBL(val) < 0) {
       rb_raise(rb_eRangeError,
-               "Assigning negative value to unsigned integer field.");
+               "Assigning negative value to unsigned integer field '%s' (given %s).",
+               name, rb_class2name(CLASS_OF(val)));
     }
   }
 }
@@ -108,12 +111,14 @@
   return value;
 }
 
-void native_slot_set(upb_fieldtype_t type, VALUE type_class,
+void native_slot_set(const char* name,
+                     upb_fieldtype_t type, VALUE type_class,
                      void* memory, VALUE value) {
-  native_slot_set_value_and_case(type, type_class, memory, value, NULL, 0);
+  native_slot_set_value_and_case(name, type, type_class, memory, value, NULL, 0);
 }
 
-void native_slot_set_value_and_case(upb_fieldtype_t type, VALUE type_class,
+void native_slot_set_value_and_case(const char* name,
+                                    upb_fieldtype_t type, VALUE type_class,
                                     void* memory, VALUE value,
                                     uint32_t* case_memory,
                                     uint32_t case_number) {
@@ -124,13 +129,15 @@
   switch (type) {
     case UPB_TYPE_FLOAT:
       if (!is_ruby_num(value)) {
-        rb_raise(cTypeError, "Expected number type for float field.");
+        rb_raise(cTypeError, "Expected number type for float field '%s' (given %s).",
+                 name, rb_class2name(CLASS_OF(value)));
       }
       DEREF(memory, float) = NUM2DBL(value);
       break;
     case UPB_TYPE_DOUBLE:
       if (!is_ruby_num(value)) {
-        rb_raise(cTypeError, "Expected number type for double field.");
+        rb_raise(cTypeError, "Expected number type for double field '%s' (given %s).",
+                 name, rb_class2name(CLASS_OF(value)));
       }
       DEREF(memory, double) = NUM2DBL(value);
       break;
@@ -141,7 +148,8 @@
       } else if (value == Qfalse) {
         val = 0;
       } else {
-        rb_raise(cTypeError, "Invalid argument for boolean field.");
+        rb_raise(cTypeError, "Invalid argument for boolean field '%s' (given %s).",
+                 name, rb_class2name(CLASS_OF(value)));
       }
       DEREF(memory, int8_t) = val;
       break;
@@ -150,7 +158,8 @@
       if (CLASS_OF(value) == rb_cSymbol) {
         value = rb_funcall(value, rb_intern("to_s"), 0);
       } else if (CLASS_OF(value) != rb_cString) {
-        rb_raise(cTypeError, "Invalid argument for string field.");
+        rb_raise(cTypeError, "Invalid argument for string field '%s' (given %s).",
+                 name, rb_class2name(CLASS_OF(value)));
       }
 
       DEREF(memory, VALUE) = native_slot_encode_and_freeze_string(type, value);
@@ -158,7 +167,8 @@
 
     case UPB_TYPE_BYTES: {
       if (CLASS_OF(value) != rb_cString) {
-        rb_raise(cTypeError, "Invalid argument for string field.");
+        rb_raise(cTypeError, "Invalid argument for bytes field '%s' (given %s).",
+                 name, rb_class2name(CLASS_OF(value)));
       }
 
       DEREF(memory, VALUE) = native_slot_encode_and_freeze_string(type, value);
@@ -169,8 +179,8 @@
         value = Qnil;
       } else if (CLASS_OF(value) != type_class) {
         rb_raise(cTypeError,
-                 "Invalid type %s to assign to submessage field.",
-                 rb_class2name(CLASS_OF(value)));
+                 "Invalid type %s to assign to submessage field '%s'.",
+                rb_class2name(CLASS_OF(value)), name);
       }
       DEREF(memory, VALUE) = value;
       break;
@@ -181,18 +191,18 @@
         value = rb_funcall(value, rb_intern("to_sym"), 0);
       } else if (!is_ruby_num(value) && TYPE(value) != T_SYMBOL) {
         rb_raise(cTypeError,
-                 "Expected number or symbol type for enum field.");
+                 "Expected number or symbol type for enum field '%s'.", name);
       }
       if (TYPE(value) == T_SYMBOL) {
         // Ensure that the given symbol exists in the enum module.
         VALUE lookup = rb_funcall(type_class, rb_intern("resolve"), 1, value);
         if (lookup == Qnil) {
-          rb_raise(rb_eRangeError, "Unknown symbol value for enum field.");
+          rb_raise(rb_eRangeError, "Unknown symbol value for enum field '%s'.", name);
         } else {
           int_val = NUM2INT(lookup);
         }
       } else {
-        native_slot_check_int_range_precision(UPB_TYPE_INT32, value);
+        native_slot_check_int_range_precision(name, UPB_TYPE_INT32, value);
         int_val = NUM2INT(value);
       }
       DEREF(memory, int32_t) = int_val;
@@ -202,7 +212,7 @@
     case UPB_TYPE_INT64:
     case UPB_TYPE_UINT32:
     case UPB_TYPE_UINT64:
-      native_slot_check_int_range_precision(type, value);
+      native_slot_check_int_range_precision(name, type, value);
       switch (type) {
       case UPB_TYPE_INT32:
         DEREF(memory, int32_t) = NUM2INT(value);
@@ -658,8 +668,9 @@
 
     DEREF(memory, VALUE) = ary;
   } else {
-    native_slot_set(upb_fielddef_type(field), field_type_class(field),
-                      memory, layout_get_default(field));
+    native_slot_set(upb_fielddef_name(field),
+                    upb_fielddef_type(field), field_type_class(field),
+                    memory, layout_get_default(field));
   }
 }
 
@@ -816,6 +827,7 @@
       // use native_slot_set_value_and_case(), which ensures that both the value
       // and case number are altered atomically (w.r.t. the Ruby VM).
       native_slot_set_value_and_case(
+          upb_fielddef_name(field),
           upb_fielddef_type(field), field_type_class(field),
           memory, val,
           oneof_case, upb_fielddef_number(field));
@@ -827,8 +839,9 @@
     check_repeated_field_type(val, field);
     DEREF(memory, VALUE) = val;
   } else {
-    native_slot_set(upb_fielddef_type(field), field_type_class(field), memory,
-		    val);
+    native_slot_set(upb_fielddef_name(field),
+                    upb_fielddef_type(field), field_type_class(field),
+                    memory, val);
   }
 
   if (layout->fields[upb_fielddef_index(field)].hasbit !=
diff --git a/ruby/ext/google/protobuf_c/upb.c b/ruby/ext/google/protobuf_c/upb.c
index b001d7a..3e52feb 100644
--- a/ruby/ext/google/protobuf_c/upb.c
+++ b/ruby/ext/google/protobuf_c/upb.c
@@ -13327,7 +13327,7 @@
   if (multipart_text(p, p->capture, *ptr - p->capture, false)) {
     /* We use this as a signal that we were in the middle of capturing, and
      * that capturing should resume at the beginning of the next buffer.
-     * 
+     *
      * We can't use *ptr here, because we have no guarantee that this pointer
      * will be valid when we resume (if the underlying memory is freed, then
      * using the pointer at all, even to compare to NULL, is likely undefined
@@ -13877,7 +13877,7 @@
     }
 
     json_parser_any_frame_set_payload_type(p, p->top->any_frame, payload_type);
-    
+
     return true;
   } else {
     upb_status_seterrf(
@@ -15134,242 +15134,242 @@
 
 #line 2556 "upb/json/parser.c"
 static const char _json_actions[] = {
-	0, 1, 0, 1, 1, 1, 3, 1, 
-	4, 1, 6, 1, 7, 1, 8, 1, 
-	9, 1, 10, 1, 11, 1, 12, 1, 
-	13, 1, 24, 1, 26, 1, 28, 1, 
-	29, 1, 31, 1, 32, 1, 33, 1, 
-	35, 1, 37, 1, 38, 1, 39, 1, 
-	40, 1, 42, 1, 43, 2, 4, 9, 
-	2, 5, 6, 2, 7, 3, 2, 7, 
-	9, 2, 14, 15, 2, 16, 17, 2, 
-	18, 19, 2, 21, 23, 2, 22, 20, 
-	2, 27, 25, 2, 29, 31, 2, 34, 
-	2, 2, 35, 43, 2, 36, 25, 2, 
-	38, 43, 2, 39, 43, 2, 40, 43, 
-	2, 41, 30, 2, 42, 43, 3, 21, 
+	0, 1, 0, 1, 1, 1, 3, 1,
+	4, 1, 6, 1, 7, 1, 8, 1,
+	9, 1, 10, 1, 11, 1, 12, 1,
+	13, 1, 24, 1, 26, 1, 28, 1,
+	29, 1, 31, 1, 32, 1, 33, 1,
+	35, 1, 37, 1, 38, 1, 39, 1,
+	40, 1, 42, 1, 43, 2, 4, 9,
+	2, 5, 6, 2, 7, 3, 2, 7,
+	9, 2, 14, 15, 2, 16, 17, 2,
+	18, 19, 2, 21, 23, 2, 22, 20,
+	2, 27, 25, 2, 29, 31, 2, 34,
+	2, 2, 35, 43, 2, 36, 25, 2,
+	38, 43, 2, 39, 43, 2, 40, 43,
+	2, 41, 30, 2, 42, 43, 3, 21,
 	23, 24, 4, 14, 15, 16, 17
 };
 
 static const short _json_key_offsets[] = {
-	0, 0, 12, 13, 18, 23, 28, 29, 
-	30, 31, 32, 33, 34, 35, 36, 37, 
-	38, 43, 44, 48, 53, 58, 63, 67, 
-	71, 74, 77, 79, 83, 87, 89, 91, 
-	96, 98, 100, 109, 115, 121, 127, 133, 
-	135, 139, 142, 144, 146, 149, 150, 154, 
-	156, 158, 160, 162, 163, 165, 167, 168, 
-	170, 172, 173, 175, 177, 178, 180, 182, 
-	183, 185, 187, 191, 193, 195, 196, 197, 
-	198, 199, 201, 206, 208, 210, 212, 221, 
-	222, 222, 222, 227, 232, 237, 238, 239, 
-	240, 241, 241, 242, 243, 244, 244, 245, 
-	246, 247, 247, 252, 253, 257, 262, 267, 
-	272, 276, 276, 279, 282, 285, 288, 291, 
+	0, 0, 12, 13, 18, 23, 28, 29,
+	30, 31, 32, 33, 34, 35, 36, 37,
+	38, 43, 44, 48, 53, 58, 63, 67,
+	71, 74, 77, 79, 83, 87, 89, 91,
+	96, 98, 100, 109, 115, 121, 127, 133,
+	135, 139, 142, 144, 146, 149, 150, 154,
+	156, 158, 160, 162, 163, 165, 167, 168,
+	170, 172, 173, 175, 177, 178, 180, 182,
+	183, 185, 187, 191, 193, 195, 196, 197,
+	198, 199, 201, 206, 208, 210, 212, 221,
+	222, 222, 222, 227, 232, 237, 238, 239,
+	240, 241, 241, 242, 243, 244, 244, 245,
+	246, 247, 247, 252, 253, 257, 262, 267,
+	272, 276, 276, 279, 282, 285, 288, 291,
 	294, 294, 294, 294, 294, 294
 };
 
 static const char _json_trans_keys[] = {
-	32, 34, 45, 91, 102, 110, 116, 123, 
-	9, 13, 48, 57, 34, 32, 93, 125, 
-	9, 13, 32, 44, 93, 9, 13, 32, 
-	93, 125, 9, 13, 97, 108, 115, 101, 
-	117, 108, 108, 114, 117, 101, 32, 34, 
-	125, 9, 13, 34, 32, 58, 9, 13, 
-	32, 93, 125, 9, 13, 32, 44, 125, 
-	9, 13, 32, 44, 125, 9, 13, 32, 
-	34, 9, 13, 45, 48, 49, 57, 48, 
-	49, 57, 46, 69, 101, 48, 57, 69, 
-	101, 48, 57, 43, 45, 48, 57, 48, 
-	57, 48, 57, 46, 69, 101, 48, 57, 
-	34, 92, 34, 92, 34, 47, 92, 98, 
-	102, 110, 114, 116, 117, 48, 57, 65, 
-	70, 97, 102, 48, 57, 65, 70, 97, 
-	102, 48, 57, 65, 70, 97, 102, 48, 
-	57, 65, 70, 97, 102, 34, 92, 45, 
-	48, 49, 57, 48, 49, 57, 46, 115, 
-	48, 57, 115, 48, 57, 34, 46, 115, 
-	48, 57, 48, 57, 48, 57, 48, 57, 
-	48, 57, 45, 48, 57, 48, 57, 45, 
-	48, 57, 48, 57, 84, 48, 57, 48, 
-	57, 58, 48, 57, 48, 57, 58, 48, 
-	57, 48, 57, 43, 45, 46, 90, 48, 
-	57, 48, 57, 58, 48, 48, 34, 48, 
-	57, 43, 45, 90, 48, 57, 34, 44, 
-	34, 44, 34, 44, 34, 45, 91, 102, 
-	110, 116, 123, 48, 57, 34, 32, 93, 
-	125, 9, 13, 32, 44, 93, 9, 13, 
-	32, 93, 125, 9, 13, 97, 108, 115, 
-	101, 117, 108, 108, 114, 117, 101, 32, 
-	34, 125, 9, 13, 34, 32, 58, 9, 
-	13, 32, 93, 125, 9, 13, 32, 44, 
-	125, 9, 13, 32, 44, 125, 9, 13, 
-	32, 34, 9, 13, 32, 9, 13, 32, 
-	9, 13, 32, 9, 13, 32, 9, 13, 
+	32, 34, 45, 91, 102, 110, 116, 123,
+	9, 13, 48, 57, 34, 32, 93, 125,
+	9, 13, 32, 44, 93, 9, 13, 32,
+	93, 125, 9, 13, 97, 108, 115, 101,
+	117, 108, 108, 114, 117, 101, 32, 34,
+	125, 9, 13, 34, 32, 58, 9, 13,
+	32, 93, 125, 9, 13, 32, 44, 125,
+	9, 13, 32, 44, 125, 9, 13, 32,
+	34, 9, 13, 45, 48, 49, 57, 48,
+	49, 57, 46, 69, 101, 48, 57, 69,
+	101, 48, 57, 43, 45, 48, 57, 48,
+	57, 48, 57, 46, 69, 101, 48, 57,
+	34, 92, 34, 92, 34, 47, 92, 98,
+	102, 110, 114, 116, 117, 48, 57, 65,
+	70, 97, 102, 48, 57, 65, 70, 97,
+	102, 48, 57, 65, 70, 97, 102, 48,
+	57, 65, 70, 97, 102, 34, 92, 45,
+	48, 49, 57, 48, 49, 57, 46, 115,
+	48, 57, 115, 48, 57, 34, 46, 115,
+	48, 57, 48, 57, 48, 57, 48, 57,
+	48, 57, 45, 48, 57, 48, 57, 45,
+	48, 57, 48, 57, 84, 48, 57, 48,
+	57, 58, 48, 57, 48, 57, 58, 48,
+	57, 48, 57, 43, 45, 46, 90, 48,
+	57, 48, 57, 58, 48, 48, 34, 48,
+	57, 43, 45, 90, 48, 57, 34, 44,
+	34, 44, 34, 44, 34, 45, 91, 102,
+	110, 116, 123, 48, 57, 34, 32, 93,
+	125, 9, 13, 32, 44, 93, 9, 13,
+	32, 93, 125, 9, 13, 97, 108, 115,
+	101, 117, 108, 108, 114, 117, 101, 32,
+	34, 125, 9, 13, 34, 32, 58, 9,
+	13, 32, 93, 125, 9, 13, 32, 44,
+	125, 9, 13, 32, 44, 125, 9, 13,
+	32, 34, 9, 13, 32, 9, 13, 32,
+	9, 13, 32, 9, 13, 32, 9, 13,
 	32, 9, 13, 32, 9, 13, 0
 };
 
 static const char _json_single_lengths[] = {
-	0, 8, 1, 3, 3, 3, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	3, 1, 2, 3, 3, 3, 2, 2, 
-	1, 3, 0, 2, 2, 0, 0, 3, 
-	2, 2, 9, 0, 0, 0, 0, 2, 
-	2, 1, 2, 0, 1, 1, 2, 0, 
-	0, 0, 0, 1, 0, 0, 1, 0, 
-	0, 1, 0, 0, 1, 0, 0, 1, 
-	0, 0, 4, 0, 0, 1, 1, 1, 
-	1, 0, 3, 2, 2, 2, 7, 1, 
-	0, 0, 3, 3, 3, 1, 1, 1, 
-	1, 0, 1, 1, 1, 0, 1, 1, 
-	1, 0, 3, 1, 2, 3, 3, 3, 
-	2, 0, 1, 1, 1, 1, 1, 1, 
+	0, 8, 1, 3, 3, 3, 1, 1,
+	1, 1, 1, 1, 1, 1, 1, 1,
+	3, 1, 2, 3, 3, 3, 2, 2,
+	1, 3, 0, 2, 2, 0, 0, 3,
+	2, 2, 9, 0, 0, 0, 0, 2,
+	2, 1, 2, 0, 1, 1, 2, 0,
+	0, 0, 0, 1, 0, 0, 1, 0,
+	0, 1, 0, 0, 1, 0, 0, 1,
+	0, 0, 4, 0, 0, 1, 1, 1,
+	1, 0, 3, 2, 2, 2, 7, 1,
+	0, 0, 3, 3, 3, 1, 1, 1,
+	1, 0, 1, 1, 1, 0, 1, 1,
+	1, 0, 3, 1, 2, 3, 3, 3,
+	2, 0, 1, 1, 1, 1, 1, 1,
 	0, 0, 0, 0, 0, 0
 };
 
 static const char _json_range_lengths[] = {
-	0, 2, 0, 1, 1, 1, 0, 0, 
-	0, 0, 0, 0, 0, 0, 0, 0, 
-	1, 0, 1, 1, 1, 1, 1, 1, 
-	1, 0, 1, 1, 1, 1, 1, 1, 
-	0, 0, 0, 3, 3, 3, 3, 0, 
-	1, 1, 0, 1, 1, 0, 1, 1, 
-	1, 1, 1, 0, 1, 1, 0, 1, 
-	1, 0, 1, 1, 0, 1, 1, 0, 
-	1, 1, 0, 1, 1, 0, 0, 0, 
-	0, 1, 1, 0, 0, 0, 1, 0, 
-	0, 0, 1, 1, 1, 0, 0, 0, 
-	0, 0, 0, 0, 0, 0, 0, 0, 
-	0, 0, 1, 0, 1, 1, 1, 1, 
-	1, 0, 1, 1, 1, 1, 1, 1, 
+	0, 2, 0, 1, 1, 1, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0,
+	1, 0, 1, 1, 1, 1, 1, 1,
+	1, 0, 1, 1, 1, 1, 1, 1,
+	0, 0, 0, 3, 3, 3, 3, 0,
+	1, 1, 0, 1, 1, 0, 1, 1,
+	1, 1, 1, 0, 1, 1, 0, 1,
+	1, 0, 1, 1, 0, 1, 1, 0,
+	1, 1, 0, 1, 1, 0, 0, 0,
+	0, 1, 1, 0, 0, 0, 1, 0,
+	0, 0, 1, 1, 1, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 1, 0, 1, 1, 1, 1,
+	1, 0, 1, 1, 1, 1, 1, 1,
 	0, 0, 0, 0, 0, 0
 };
 
 static const short _json_index_offsets[] = {
-	0, 0, 11, 13, 18, 23, 28, 30, 
-	32, 34, 36, 38, 40, 42, 44, 46, 
-	48, 53, 55, 59, 64, 69, 74, 78, 
-	82, 85, 89, 91, 95, 99, 101, 103, 
-	108, 111, 114, 124, 128, 132, 136, 140, 
-	143, 147, 150, 153, 155, 158, 160, 164, 
-	166, 168, 170, 172, 174, 176, 178, 180, 
-	182, 184, 186, 188, 190, 192, 194, 196, 
-	198, 200, 202, 207, 209, 211, 213, 215, 
-	217, 219, 221, 226, 229, 232, 235, 244, 
-	246, 247, 248, 253, 258, 263, 265, 267, 
-	269, 271, 272, 274, 276, 278, 279, 281, 
-	283, 285, 286, 291, 293, 297, 302, 307, 
-	312, 316, 317, 320, 323, 326, 329, 332, 
+	0, 0, 11, 13, 18, 23, 28, 30,
+	32, 34, 36, 38, 40, 42, 44, 46,
+	48, 53, 55, 59, 64, 69, 74, 78,
+	82, 85, 89, 91, 95, 99, 101, 103,
+	108, 111, 114, 124, 128, 132, 136, 140,
+	143, 147, 150, 153, 155, 158, 160, 164,
+	166, 168, 170, 172, 174, 176, 178, 180,
+	182, 184, 186, 188, 190, 192, 194, 196,
+	198, 200, 202, 207, 209, 211, 213, 215,
+	217, 219, 221, 226, 229, 232, 235, 244,
+	246, 247, 248, 253, 258, 263, 265, 267,
+	269, 271, 272, 274, 276, 278, 279, 281,
+	283, 285, 286, 291, 293, 297, 302, 307,
+	312, 316, 317, 320, 323, 326, 329, 332,
 	335, 336, 337, 338, 339, 340
 };
 
 static const unsigned char _json_indicies[] = {
-	0, 2, 3, 4, 5, 6, 7, 8, 
-	0, 3, 1, 9, 1, 11, 12, 1, 
-	11, 10, 13, 14, 12, 13, 1, 14, 
-	1, 1, 14, 10, 15, 1, 16, 1, 
-	17, 1, 18, 1, 19, 1, 20, 1, 
-	21, 1, 22, 1, 23, 1, 24, 1, 
-	25, 26, 27, 25, 1, 28, 1, 29, 
-	30, 29, 1, 30, 1, 1, 30, 31, 
-	32, 33, 34, 32, 1, 35, 36, 27, 
-	35, 1, 36, 26, 36, 1, 37, 38, 
-	39, 1, 38, 39, 1, 41, 42, 42, 
-	40, 43, 1, 42, 42, 43, 40, 44, 
-	44, 45, 1, 45, 1, 45, 40, 41, 
-	42, 42, 39, 40, 47, 48, 46, 50, 
-	51, 49, 52, 52, 52, 52, 52, 52, 
-	52, 52, 53, 1, 54, 54, 54, 1, 
-	55, 55, 55, 1, 56, 56, 56, 1, 
-	57, 57, 57, 1, 59, 60, 58, 61, 
-	62, 63, 1, 64, 65, 1, 66, 67, 
-	1, 68, 1, 67, 68, 1, 69, 1, 
-	66, 67, 65, 1, 70, 1, 71, 1, 
-	72, 1, 73, 1, 74, 1, 75, 1, 
-	76, 1, 77, 1, 78, 1, 79, 1, 
-	80, 1, 81, 1, 82, 1, 83, 1, 
-	84, 1, 85, 1, 86, 1, 87, 1, 
-	88, 1, 89, 89, 90, 91, 1, 92, 
-	1, 93, 1, 94, 1, 95, 1, 96, 
-	1, 97, 1, 98, 1, 99, 99, 100, 
-	98, 1, 102, 1, 101, 104, 105, 103, 
-	1, 1, 101, 106, 107, 108, 109, 110, 
-	111, 112, 107, 1, 113, 1, 114, 115, 
-	117, 118, 1, 117, 116, 119, 120, 118, 
-	119, 1, 120, 1, 1, 120, 116, 121, 
-	1, 122, 1, 123, 1, 124, 1, 125, 
-	126, 1, 127, 1, 128, 1, 129, 130, 
-	1, 131, 1, 132, 1, 133, 134, 135, 
-	136, 134, 1, 137, 1, 138, 139, 138, 
-	1, 139, 1, 1, 139, 140, 141, 142, 
-	143, 141, 1, 144, 145, 136, 144, 1, 
-	145, 135, 145, 1, 146, 147, 147, 1, 
-	148, 148, 1, 149, 149, 1, 150, 150, 
-	1, 151, 151, 1, 152, 152, 1, 1, 
+	0, 2, 3, 4, 5, 6, 7, 8,
+	0, 3, 1, 9, 1, 11, 12, 1,
+	11, 10, 13, 14, 12, 13, 1, 14,
+	1, 1, 14, 10, 15, 1, 16, 1,
+	17, 1, 18, 1, 19, 1, 20, 1,
+	21, 1, 22, 1, 23, 1, 24, 1,
+	25, 26, 27, 25, 1, 28, 1, 29,
+	30, 29, 1, 30, 1, 1, 30, 31,
+	32, 33, 34, 32, 1, 35, 36, 27,
+	35, 1, 36, 26, 36, 1, 37, 38,
+	39, 1, 38, 39, 1, 41, 42, 42,
+	40, 43, 1, 42, 42, 43, 40, 44,
+	44, 45, 1, 45, 1, 45, 40, 41,
+	42, 42, 39, 40, 47, 48, 46, 50,
+	51, 49, 52, 52, 52, 52, 52, 52,
+	52, 52, 53, 1, 54, 54, 54, 1,
+	55, 55, 55, 1, 56, 56, 56, 1,
+	57, 57, 57, 1, 59, 60, 58, 61,
+	62, 63, 1, 64, 65, 1, 66, 67,
+	1, 68, 1, 67, 68, 1, 69, 1,
+	66, 67, 65, 1, 70, 1, 71, 1,
+	72, 1, 73, 1, 74, 1, 75, 1,
+	76, 1, 77, 1, 78, 1, 79, 1,
+	80, 1, 81, 1, 82, 1, 83, 1,
+	84, 1, 85, 1, 86, 1, 87, 1,
+	88, 1, 89, 89, 90, 91, 1, 92,
+	1, 93, 1, 94, 1, 95, 1, 96,
+	1, 97, 1, 98, 1, 99, 99, 100,
+	98, 1, 102, 1, 101, 104, 105, 103,
+	1, 1, 101, 106, 107, 108, 109, 110,
+	111, 112, 107, 1, 113, 1, 114, 115,
+	117, 118, 1, 117, 116, 119, 120, 118,
+	119, 1, 120, 1, 1, 120, 116, 121,
+	1, 122, 1, 123, 1, 124, 1, 125,
+	126, 1, 127, 1, 128, 1, 129, 130,
+	1, 131, 1, 132, 1, 133, 134, 135,
+	136, 134, 1, 137, 1, 138, 139, 138,
+	1, 139, 1, 1, 139, 140, 141, 142,
+	143, 141, 1, 144, 145, 136, 144, 1,
+	145, 135, 145, 1, 146, 147, 147, 1,
+	148, 148, 1, 149, 149, 1, 150, 150,
+	1, 151, 151, 1, 152, 152, 1, 1,
 	1, 1, 1, 1, 1, 0
 };
 
 static const char _json_trans_targs[] = {
-	1, 0, 2, 107, 3, 6, 10, 13, 
-	16, 106, 4, 3, 106, 4, 5, 7, 
-	8, 9, 108, 11, 12, 109, 14, 15, 
-	110, 16, 17, 111, 18, 18, 19, 20, 
-	21, 22, 111, 21, 22, 24, 25, 31, 
-	112, 26, 28, 27, 29, 30, 33, 113, 
-	34, 33, 113, 34, 32, 35, 36, 37, 
-	38, 39, 33, 113, 34, 41, 42, 46, 
-	42, 46, 43, 45, 44, 114, 48, 49, 
-	50, 51, 52, 53, 54, 55, 56, 57, 
-	58, 59, 60, 61, 62, 63, 64, 65, 
-	66, 67, 73, 72, 68, 69, 70, 71, 
-	72, 115, 74, 67, 72, 76, 116, 76, 
-	116, 77, 79, 81, 82, 85, 90, 94, 
-	98, 80, 117, 117, 83, 82, 80, 83, 
-	84, 86, 87, 88, 89, 117, 91, 92, 
-	93, 117, 95, 96, 97, 117, 98, 99, 
-	105, 100, 100, 101, 102, 103, 104, 105, 
-	103, 104, 117, 106, 106, 106, 106, 106, 
+	1, 0, 2, 107, 3, 6, 10, 13,
+	16, 106, 4, 3, 106, 4, 5, 7,
+	8, 9, 108, 11, 12, 109, 14, 15,
+	110, 16, 17, 111, 18, 18, 19, 20,
+	21, 22, 111, 21, 22, 24, 25, 31,
+	112, 26, 28, 27, 29, 30, 33, 113,
+	34, 33, 113, 34, 32, 35, 36, 37,
+	38, 39, 33, 113, 34, 41, 42, 46,
+	42, 46, 43, 45, 44, 114, 48, 49,
+	50, 51, 52, 53, 54, 55, 56, 57,
+	58, 59, 60, 61, 62, 63, 64, 65,
+	66, 67, 73, 72, 68, 69, 70, 71,
+	72, 115, 74, 67, 72, 76, 116, 76,
+	116, 77, 79, 81, 82, 85, 90, 94,
+	98, 80, 117, 117, 83, 82, 80, 83,
+	84, 86, 87, 88, 89, 117, 91, 92,
+	93, 117, 95, 96, 97, 117, 98, 99,
+	105, 100, 100, 101, 102, 103, 104, 105,
+	103, 104, 117, 106, 106, 106, 106, 106,
 	106
 };
 
 static const char _json_trans_actions[] = {
-	0, 0, 92, 86, 35, 0, 0, 0, 
-	104, 41, 27, 0, 37, 0, 0, 0, 
-	0, 0, 0, 0, 0, 0, 0, 0, 
-	0, 0, 80, 33, 29, 0, 0, 27, 
-	31, 31, 83, 0, 0, 0, 0, 0, 
-	3, 0, 0, 0, 0, 0, 5, 15, 
-	0, 0, 53, 7, 13, 0, 56, 9, 
-	9, 9, 59, 62, 11, 17, 17, 17, 
-	0, 0, 0, 19, 0, 21, 23, 0, 
-	0, 0, 0, 0, 0, 0, 0, 0, 
-	0, 0, 0, 0, 0, 0, 0, 0, 
-	0, 114, 65, 114, 0, 0, 0, 0, 
-	0, 71, 0, 68, 68, 77, 25, 0, 
-	110, 74, 92, 86, 35, 0, 0, 0, 
-	104, 41, 51, 89, 27, 0, 37, 0, 
-	0, 0, 0, 0, 0, 98, 0, 0, 
-	0, 101, 0, 0, 0, 95, 0, 80, 
-	33, 29, 0, 0, 27, 31, 31, 83, 
-	0, 0, 107, 0, 39, 45, 47, 43, 
+	0, 0, 92, 86, 35, 0, 0, 0,
+	104, 41, 27, 0, 37, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 80, 33, 29, 0, 0, 27,
+	31, 31, 83, 0, 0, 0, 0, 0,
+	3, 0, 0, 0, 0, 0, 5, 15,
+	0, 0, 53, 7, 13, 0, 56, 9,
+	9, 9, 59, 62, 11, 17, 17, 17,
+	0, 0, 0, 19, 0, 21, 23, 0,
+	0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0,
+	0, 114, 65, 114, 0, 0, 0, 0,
+	0, 71, 0, 68, 68, 77, 25, 0,
+	110, 74, 92, 86, 35, 0, 0, 0,
+	104, 41, 51, 89, 27, 0, 37, 0,
+	0, 0, 0, 0, 0, 98, 0, 0,
+	0, 101, 0, 0, 0, 95, 0, 80,
+	33, 29, 0, 0, 27, 31, 31, 83,
+	0, 0, 107, 0, 39, 45, 47, 43,
 	49
 };
 
 static const char _json_eof_actions[] = {
-	0, 0, 0, 0, 0, 0, 0, 0, 
-	0, 0, 0, 0, 0, 0, 0, 0, 
-	0, 0, 0, 0, 0, 0, 0, 0, 
-	0, 1, 0, 1, 0, 0, 1, 1, 
-	0, 0, 0, 0, 0, 0, 0, 0, 
-	0, 0, 0, 0, 0, 0, 0, 0, 
-	0, 0, 0, 0, 0, 0, 0, 0, 
-	0, 0, 0, 0, 0, 0, 0, 0, 
-	0, 0, 0, 0, 0, 0, 0, 0, 
-	0, 0, 0, 0, 0, 0, 0, 0, 
-	0, 0, 0, 0, 0, 0, 0, 0, 
-	0, 0, 0, 0, 0, 0, 0, 0, 
-	0, 0, 0, 0, 0, 0, 0, 0, 
-	0, 0, 0, 39, 45, 47, 43, 49, 
+	0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0,
+	0, 1, 0, 1, 0, 0, 1, 1,
+	0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 39, 45, 47, 43, 49,
 	0, 0, 0, 0, 0, 0
 };
 
@@ -15406,7 +15406,7 @@
 
   capture_resume(parser, buf);
 
-  
+
 #line 2831 "upb/json/parser.c"
 	{
 	int _klen;
@@ -15785,7 +15785,7 @@
   p->top->is_unknown_field = false;
 
   /* Emit Ragel initialization of the parser. */
-  
+
 #line 3210 "upb/json/parser.c"
 	{
 	cs = json_start;
diff --git a/ruby/ext/google/protobuf_c/upb.h b/ruby/ext/google/protobuf_c/upb.h
index 7b3981b..9112aba 100644
--- a/ruby/ext/google/protobuf_c/upb.h
+++ b/ruby/ext/google/protobuf_c/upb.h
@@ -5036,7 +5036,7 @@
 
 /* BoundFunc2, BoundFunc3: Like Func2/Func3 except also contains a value that
  * shall be bound to the function's second parameter.
- * 
+ *
  * Note that the second parameter is a const pointer, but our stored bound value
  * is non-const so we can free it when the handlers are destroyed. */
 template <class T>
diff --git a/ruby/src/main/java/com/google/protobuf/jruby/SentinelOuterClass.java b/ruby/src/main/java/com/google/protobuf/jruby/SentinelOuterClass.java
index 54f2c72..b3f23c5 100644
--- a/ruby/src/main/java/com/google/protobuf/jruby/SentinelOuterClass.java
+++ b/ruby/src/main/java/com/google/protobuf/jruby/SentinelOuterClass.java
@@ -204,7 +204,7 @@
       if (ref instanceof java.lang.String) {
         return (java.lang.String) ref;
       } else {
-        com.google.protobuf.ByteString bs = 
+        com.google.protobuf.ByteString bs =
             (com.google.protobuf.ByteString) ref;
         java.lang.String s = bs.toStringUtf8();
         if (bs.isValidUtf8()) {
@@ -220,7 +220,7 @@
         getDefaultStringBytes() {
       java.lang.Object ref = defaultString_;
       if (ref instanceof java.lang.String) {
-        com.google.protobuf.ByteString b = 
+        com.google.protobuf.ByteString b =
             com.google.protobuf.ByteString.copyFromUtf8(
                 (java.lang.String) ref);
         defaultString_ = b;
@@ -432,7 +432,7 @@
        * <code>optional int32 default_int32 = 1;</code>
        */
       public Builder setDefaultInt32(int value) {
-        
+
         defaultInt32_ = value;
         onChanged();
         return this;
@@ -441,7 +441,7 @@
        * <code>optional int32 default_int32 = 1;</code>
        */
       public Builder clearDefaultInt32() {
-        
+
         defaultInt32_ = 0;
         onChanged();
         return this;
@@ -458,7 +458,7 @@
        * <code>optional int64 default_int64 = 2;</code>
        */
       public Builder setDefaultInt64(long value) {
-        
+
         defaultInt64_ = value;
         onChanged();
         return this;
@@ -467,7 +467,7 @@
        * <code>optional int64 default_int64 = 2;</code>
        */
       public Builder clearDefaultInt64() {
-        
+
         defaultInt64_ = 0L;
         onChanged();
         return this;
@@ -484,7 +484,7 @@
        * <code>optional uint32 default_unit32 = 3;</code>
        */
       public Builder setDefaultUnit32(int value) {
-        
+
         defaultUnit32_ = value;
         onChanged();
         return this;
@@ -493,7 +493,7 @@
        * <code>optional uint32 default_unit32 = 3;</code>
        */
       public Builder clearDefaultUnit32() {
-        
+
         defaultUnit32_ = 0;
         onChanged();
         return this;
@@ -510,7 +510,7 @@
        * <code>optional uint64 default_uint64 = 4;</code>
        */
       public Builder setDefaultUint64(long value) {
-        
+
         defaultUint64_ = value;
         onChanged();
         return this;
@@ -519,7 +519,7 @@
        * <code>optional uint64 default_uint64 = 4;</code>
        */
       public Builder clearDefaultUint64() {
-        
+
         defaultUint64_ = 0L;
         onChanged();
         return this;
@@ -550,7 +550,7 @@
           getDefaultStringBytes() {
         java.lang.Object ref = defaultString_;
         if (ref instanceof String) {
-          com.google.protobuf.ByteString b = 
+          com.google.protobuf.ByteString b =
               com.google.protobuf.ByteString.copyFromUtf8(
                   (java.lang.String) ref);
           defaultString_ = b;
@@ -567,7 +567,7 @@
         if (value == null) {
     throw new NullPointerException();
   }
-  
+
         defaultString_ = value;
         onChanged();
         return this;
@@ -576,7 +576,7 @@
        * <code>optional string default_string = 5;</code>
        */
       public Builder clearDefaultString() {
-        
+
         defaultString_ = getDefaultInstance().getDefaultString();
         onChanged();
         return this;
@@ -589,7 +589,7 @@
         if (value == null) {
     throw new NullPointerException();
   }
-  
+
         defaultString_ = value;
         onChanged();
         return this;
@@ -606,7 +606,7 @@
        * <code>optional bool default_bool = 6;</code>
        */
       public Builder setDefaultBool(boolean value) {
-        
+
         defaultBool_ = value;
         onChanged();
         return this;
@@ -615,7 +615,7 @@
        * <code>optional bool default_bool = 6;</code>
        */
       public Builder clearDefaultBool() {
-        
+
         defaultBool_ = false;
         onChanged();
         return this;
@@ -632,7 +632,7 @@
        * <code>optional float default_float = 7;</code>
        */
       public Builder setDefaultFloat(float value) {
-        
+
         defaultFloat_ = value;
         onChanged();
         return this;
@@ -641,7 +641,7 @@
        * <code>optional float default_float = 7;</code>
        */
       public Builder clearDefaultFloat() {
-        
+
         defaultFloat_ = 0F;
         onChanged();
         return this;
@@ -658,7 +658,7 @@
        * <code>optional double default_double = 8;</code>
        */
       public Builder setDefaultDouble(double value) {
-        
+
         defaultDouble_ = value;
         onChanged();
         return this;
@@ -667,7 +667,7 @@
        * <code>optional double default_double = 8;</code>
        */
       public Builder clearDefaultDouble() {
-        
+
         defaultDouble_ = 0D;
         onChanged();
         return this;
@@ -687,7 +687,7 @@
         if (value == null) {
     throw new NullPointerException();
   }
-  
+
         defaultBytes_ = value;
         onChanged();
         return this;
@@ -696,7 +696,7 @@
        * <code>optional bytes default_bytes = 9;</code>
        */
       public Builder clearDefaultBytes() {
-        
+
         defaultBytes_ = getDefaultInstance().getDefaultBytes();
         onChanged();
         return this;
diff --git a/ruby/tests/basic.rb b/ruby/tests/basic.rb
index 5e17bef..269c9ee 100644
--- a/ruby/tests/basic.rb
+++ b/ruby/tests/basic.rb
@@ -154,12 +154,12 @@
       e = assert_raise ArgumentError do
         MapMessage.new(:map_string_int32 => "hello")
       end
-      assert_equal e.message, "Expected Hash object as initializer value for map field 'map_string_int32'."
+      assert_equal e.message, "Expected Hash object as initializer value for map field 'map_string_int32' (given String)."
 
       e = assert_raise ArgumentError do
         TestMessage.new(:repeated_uint32 => "hello")
       end
-      assert_equal e.message, "Expected array as initializer value for repeated field 'repeated_uint32'."
+      assert_equal e.message, "Expected array as initializer value for repeated field 'repeated_uint32' (given String)."
     end
 
     def test_map_field
diff --git a/ruby/tests/basic_proto2.rb b/ruby/tests/basic_proto2.rb
index a59e808..53d6a70 100644
--- a/ruby/tests/basic_proto2.rb
+++ b/ruby/tests/basic_proto2.rb
@@ -207,7 +207,7 @@
       e = assert_raise ArgumentError do
         TestMessage.new(:repeated_uint32 => "hello")
       end
-      assert_equal e.message, "Expected array as initializer value for repeated field 'repeated_uint32'."
+      assert_equal e.message, "Expected array as initializer value for repeated field 'repeated_uint32' (given String)."
     end
 
 
diff --git a/ruby/tests/common_tests.rb b/ruby/tests/common_tests.rb
index 60897b6..a9c44f5 100644
--- a/ruby/tests/common_tests.rb
+++ b/ruby/tests/common_tests.rb
@@ -103,7 +103,7 @@
     assert_equal 3, m.repeated_msg.first.sub_child.optional_int32
   end
 
-  def test_inspect
+  def test_inspect_eq_to_s
     m = proto_module::TestMessage.new(
       :optional_int32 => -42,
       :optional_enum => :A,
@@ -111,10 +111,12 @@
       :repeated_string => ["hello", "there", "world"])
     expected = "<#{proto_module}::TestMessage: optional_int32: -42, optional_int64: 0, optional_uint32: 0, optional_uint64: 0, optional_bool: false, optional_float: 0.0, optional_double: 0.0, optional_string: \"\", optional_bytes: \"\", optional_msg: <#{proto_module}::TestMessage2: foo: 0>, optional_enum: :A, repeated_int32: [], repeated_int64: [], repeated_uint32: [], repeated_uint64: [], repeated_bool: [], repeated_float: [], repeated_double: [], repeated_string: [\"hello\", \"there\", \"world\"], repeated_bytes: [], repeated_msg: [], repeated_enum: []>"
     assert_equal expected, m.inspect
+    assert_equal expected, m.to_s
 
     m = proto_module::OneofMessage.new(:b => -42)
     expected = "<#{proto_module}::OneofMessage: a: \"\", b: -42, c: nil, d: :Default>"
     assert_equal expected, m.inspect
+    assert_equal expected, m.to_s
   end
 
   def test_hash
@@ -1117,4 +1119,25 @@
   def test_comparison_with_arbitrary_object
     assert proto_module::TestMessage.new != nil
   end
+
+  def test_eq
+    m1 = proto_module::TestMessage.new(:optional_string => 'foo', :repeated_string => ['bar1', 'bar2'])
+    m2 = proto_module::TestMessage.new(:optional_string => 'foo', :repeated_string => ['bar1', 'bar2'])
+
+    h = {}
+    h[m1] = :yes
+
+    assert m1 == m2
+    assert m1.eql?(m2)
+    assert m1.hash == m2.hash
+    assert h[m1] == :yes
+    assert h[m2] == :yes
+
+    m1.optional_int32 = 2
+
+    assert m1 != m2
+    assert !m1.eql?(m2)
+    assert m1.hash != m2.hash
+    assert_nil h[m2]
+  end
 end
diff --git a/ruby/tests/type_errors.rb b/ruby/tests/type_errors.rb
new file mode 100644
index 0000000..76c591c
--- /dev/null
+++ b/ruby/tests/type_errors.rb
@@ -0,0 +1,173 @@
+#!/usr/bin/ruby
+
+# generated_code.rb is in the same directory as this test.
+$LOAD_PATH.unshift(File.expand_path(File.dirname(__FILE__)))
+
+require 'test/unit'
+require 'google/protobuf/well_known_types'
+require 'generated_code_pb'
+
+class TestTypeErrors < Test::Unit::TestCase
+  def test_bad_string
+    check_error Google::Protobuf::TypeError,
+                "Invalid argument for string field 'optional_string' (given Integer)." do
+      A::B::C::TestMessage.new(optional_string: 4)
+    end
+    check_error Google::Protobuf::TypeError,
+                "Invalid argument for string field 'oneof_string' (given Integer)." do
+      A::B::C::TestMessage.new(oneof_string: 4)
+    end
+    check_error ArgumentError,
+                "Expected array as initializer value for repeated field 'repeated_string' (given String)." do
+      A::B::C::TestMessage.new(repeated_string: '4')
+    end
+  end
+
+  def test_bad_float
+    check_error Google::Protobuf::TypeError,
+                "Expected number type for float field 'optional_float' (given TrueClass)." do
+      A::B::C::TestMessage.new(optional_float: true)
+    end
+    check_error Google::Protobuf::TypeError,
+                "Expected number type for float field 'oneof_float' (given TrueClass)." do
+      A::B::C::TestMessage.new(oneof_float: true)
+    end
+    check_error ArgumentError,
+                "Expected array as initializer value for repeated field 'repeated_float' (given String)." do
+      A::B::C::TestMessage.new(repeated_float: 'true')
+    end
+  end
+
+  def test_bad_double
+    check_error Google::Protobuf::TypeError,
+                "Expected number type for double field 'optional_double' (given Symbol)." do
+      A::B::C::TestMessage.new(optional_double: :double)
+    end
+    check_error Google::Protobuf::TypeError,
+                "Expected number type for double field 'oneof_double' (given Symbol)." do
+      A::B::C::TestMessage.new(oneof_double: :double)
+    end
+    check_error ArgumentError,
+                "Expected array as initializer value for repeated field 'repeated_double' (given FalseClass)." do
+      A::B::C::TestMessage.new(repeated_double: false)
+    end
+  end
+
+  def test_bad_bool
+    check_error Google::Protobuf::TypeError,
+                "Invalid argument for boolean field 'optional_bool' (given Float)." do
+      A::B::C::TestMessage.new(optional_bool: 4.4)
+    end
+    check_error Google::Protobuf::TypeError,
+                "Invalid argument for boolean field 'oneof_bool' (given Float)." do
+      A::B::C::TestMessage.new(oneof_bool: 4.4)
+    end
+    check_error ArgumentError,
+                "Expected array as initializer value for repeated field 'repeated_bool' (given String)." do
+      A::B::C::TestMessage.new(repeated_bool: 'hi')
+    end
+  end
+
+  def test_bad_int
+    check_error Google::Protobuf::TypeError,
+                "Expected number type for integral field 'optional_int32' (given String)." do
+      A::B::C::TestMessage.new(optional_int32: 'hi')
+    end
+    check_error RangeError,
+                "Non-integral floating point value assigned to integer field 'optional_int64' (given Float)." do
+      A::B::C::TestMessage.new(optional_int64: 2.4)
+    end
+    check_error Google::Protobuf::TypeError,
+                "Expected number type for integral field 'optional_uint32' (given Symbol)." do
+      A::B::C::TestMessage.new(optional_uint32: :thing)
+    end
+    check_error Google::Protobuf::TypeError,
+                "Expected number type for integral field 'optional_uint64' (given FalseClass)." do
+      A::B::C::TestMessage.new(optional_uint64: false)
+    end
+    check_error Google::Protobuf::TypeError,
+                "Expected number type for integral field 'oneof_int32' (given Symbol)." do
+      A::B::C::TestMessage.new(oneof_int32: :hi)
+    end
+    check_error RangeError,
+                "Non-integral floating point value assigned to integer field 'oneof_int64' (given Float)." do
+      A::B::C::TestMessage.new(oneof_int64: 2.4)
+    end
+    check_error Google::Protobuf::TypeError,
+                "Expected number type for integral field 'oneof_uint32' (given String)." do
+      A::B::C::TestMessage.new(oneof_uint32: 'x')
+    end
+    check_error RangeError,
+                "Non-integral floating point value assigned to integer field 'oneof_uint64' (given Float)." do
+      A::B::C::TestMessage.new(oneof_uint64: 1.1)
+    end
+    check_error ArgumentError,
+                "Expected array as initializer value for repeated field 'repeated_int32' (given Symbol)." do
+      A::B::C::TestMessage.new(repeated_int32: :hi)
+    end
+    check_error ArgumentError,
+                "Expected array as initializer value for repeated field 'repeated_int64' (given Float)." do
+      A::B::C::TestMessage.new(repeated_int64: 2.4)
+    end
+    check_error ArgumentError,
+                "Expected array as initializer value for repeated field 'repeated_uint32' (given String)." do
+      A::B::C::TestMessage.new(repeated_uint32: 'x')
+    end
+    check_error ArgumentError,
+                "Expected array as initializer value for repeated field 'repeated_uint64' (given Float)." do
+      A::B::C::TestMessage.new(repeated_uint64: 1.1)
+    end
+  end
+
+  def test_bad_enum
+    check_error RangeError,
+                "Unknown symbol value for enum field 'optional_enum'." do
+      A::B::C::TestMessage.new(optional_enum: 'enum')
+    end
+    check_error RangeError,
+                "Unknown symbol value for enum field 'oneof_enum'." do
+      A::B::C::TestMessage.new(oneof_enum: '')
+    end
+    check_error ArgumentError,
+                "Expected array as initializer value for repeated field 'repeated_enum' (given String)." do
+      A::B::C::TestMessage.new(repeated_enum: '')
+    end
+  end
+
+  def test_bad_bytes
+    check_error Google::Protobuf::TypeError,
+                "Invalid argument for bytes field 'optional_bytes' (given Float)." do
+      A::B::C::TestMessage.new(optional_bytes: 22.22)
+    end
+    check_error Google::Protobuf::TypeError,
+                "Invalid argument for bytes field 'oneof_bytes' (given Symbol)." do
+      A::B::C::TestMessage.new(oneof_bytes: :T22)
+    end
+    check_error ArgumentError,
+                "Expected array as initializer value for repeated field 'repeated_bytes' (given Symbol)." do
+      A::B::C::TestMessage.new(repeated_bytes: :T22)
+    end
+  end
+
+  def test_bad_msg
+    check_error Google::Protobuf::TypeError,
+                "Invalid type Integer to assign to submessage field 'optional_msg'." do
+      A::B::C::TestMessage.new(optional_msg: 2)
+    end
+    check_error Google::Protobuf::TypeError,
+                "Invalid type String to assign to submessage field 'oneof_msg'." do
+      A::B::C::TestMessage.new(oneof_msg: '2')
+    end
+    check_error ArgumentError,
+                "Expected array as initializer value for repeated field 'repeated_msg' (given String)." do
+      A::B::C::TestMessage.new(repeated_msg: '2')
+    end
+  end
+
+  def check_error(type, message)
+    err = assert_raises type do
+      yield
+    end
+    assert_equal message, err.message
+  end
+end
diff --git a/src/google/protobuf/compiler/csharp/csharp_field_base.cc b/src/google/protobuf/compiler/csharp/csharp_field_base.cc
index f880826..90b01b6 100644
--- a/src/google/protobuf/compiler/csharp/csharp_field_base.cc
+++ b/src/google/protobuf/compiler/csharp/csharp_field_base.cc
@@ -303,7 +303,7 @@
   switch (descriptor->type()) {
     case FieldDescriptor::TYPE_ENUM:
       if (IsProto2(descriptor_->file())) {
-        return GetClassName(descriptor->default_value_enum()->type()) + "." + 
+        return GetClassName(descriptor->default_value_enum()->type()) + "." +
           GetEnumValueName(descriptor->default_value_enum()->type()->name(), descriptor->default_value_enum()->name());
       }
       else {
diff --git a/src/google/protobuf/compiler/csharp/csharp_generator.cc b/src/google/protobuf/compiler/csharp/csharp_generator.cc
index d23fdb0..5b01629 100644
--- a/src/google/protobuf/compiler/csharp/csharp_generator.cc
+++ b/src/google/protobuf/compiler/csharp/csharp_generator.cc
@@ -65,11 +65,11 @@
   std::vector<std::pair<string, string> > options;
   ParseGeneratorParameter(parameter, &options);
 
-  // We only support proto3 - but we make an exception for descriptor.proto. 
+  // We only support proto3 - but we make an exception for descriptor.proto.
   if (file->syntax() != FileDescriptor::SYNTAX_PROTO3 && !IsDescriptorProto(file)) {
-    *error = "C# code generation only supports proto3 syntax"; 
+    *error = "C# code generation only supports proto3 syntax";
     return false;
-  } 
+  }
 
   struct Options cli_options;
 
diff --git a/src/google/protobuf/compiler/csharp/csharp_helpers.cc b/src/google/protobuf/compiler/csharp/csharp_helpers.cc
index dace410..74dd0c9 100644
--- a/src/google/protobuf/compiler/csharp/csharp_helpers.cc
+++ b/src/google/protobuf/compiler/csharp/csharp_helpers.cc
@@ -198,7 +198,7 @@
     char current = input[i];
     if (!ascii_isalnum(current)) {
       previous = current;
-      continue;      
+      continue;
     }
     if (!ascii_isalnum(previous)) {
       result += ascii_toupper(current);
@@ -228,7 +228,7 @@
       prefix_to_match += ascii_tolower(prefix[i]);
     }
   }
-  
+
   // This keeps track of how much of value we've consumed
   size_t prefix_index, value_index;
   for (prefix_index = 0, value_index = 0;
@@ -278,6 +278,19 @@
   return result;
 }
 
+uint GetGroupEndTag(const Descriptor* descriptor) {
+  const Descriptor* containing_type = descriptor->containing_type();
+  if (containing_type == NULL) {
+    return 0;
+  }
+  const FieldDescriptor* field = containing_type->FindFieldByName(descriptor->name());
+  if (field != NULL && field->type() == FieldDescriptor::Type::TYPE_GROUP) {
+    return internal::WireFormatLite::MakeTag(field->number(), internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED);
+  } else {
+    return 0;
+  }
+}
+
 std::string ToCSharpName(const std::string& name, const FileDescriptor* file) {
   std::string result = GetFileNamespace(file);
   if (result != "") {
diff --git a/src/google/protobuf/compiler/csharp/csharp_helpers.h b/src/google/protobuf/compiler/csharp/csharp_helpers.h
index 5b9f90e..d351a1c 100644
--- a/src/google/protobuf/compiler/csharp/csharp_helpers.h
+++ b/src/google/protobuf/compiler/csharp/csharp_helpers.h
@@ -118,6 +118,9 @@
   return descriptor->options().map_entry();
 }
 
+// Checks if this descriptor is for a group and gets its end tag or 0 if it's not a group
+uint GetGroupEndTag(const Descriptor* descriptor);
+
 // Determines whether we're generating code for the proto representation of
 // descriptors etc, for use in the runtime. This is the only type which is
 // allowed to use proto2 syntax, and it generates internal classes.
diff --git a/src/google/protobuf/compiler/csharp/csharp_map_field.cc b/src/google/protobuf/compiler/csharp/csharp_map_field.cc
index 125bdf1..3519f18 100644
--- a/src/google/protobuf/compiler/csharp/csharp_map_field.cc
+++ b/src/google/protobuf/compiler/csharp/csharp_map_field.cc
@@ -56,7 +56,7 @@
 MapFieldGenerator::~MapFieldGenerator() {
 }
 
-void MapFieldGenerator::GenerateMembers(io::Printer* printer) {   
+void MapFieldGenerator::GenerateMembers(io::Printer* printer) {
   const FieldDescriptor* key_descriptor =
       descriptor_->message_type()->FindFieldByName("key");
   const FieldDescriptor* value_descriptor =
diff --git a/src/google/protobuf/compiler/csharp/csharp_message.cc b/src/google/protobuf/compiler/csharp/csharp_message.cc
index be1cd11..7157580 100644
--- a/src/google/protobuf/compiler/csharp/csharp_message.cc
+++ b/src/google/protobuf/compiler/csharp/csharp_message.cc
@@ -63,7 +63,8 @@
                                    const Options* options)
     : SourceGeneratorBase(descriptor->file(), options),
       descriptor_(descriptor),
-      has_bit_field_count_(0) {
+      has_bit_field_count_(0),
+      end_tag_(GetGroupEndTag(descriptor)) {
   // fields by number
   for (int i = 0; i < descriptor_->field_count(); i++) {
     fields_by_number_.push_back(descriptor_->field(i));
@@ -486,7 +487,7 @@
     "}\n");
   // Merge non-oneof fields
   for (int i = 0; i < descriptor_->field_count(); i++) {
-    if (!descriptor_->field(i)->containing_oneof()) {      
+    if (!descriptor_->field(i)->containing_oneof()) {
       std::unique_ptr<FieldGeneratorBase> generator(
           CreateFieldGeneratorInternal(descriptor_->field(i)));
       generator->GenerateMergingCode(printer);
@@ -539,10 +540,14 @@
   } else {
     printer->Print(
       "default:\n"
-      "  if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {\n"
-      "    return;\n"
-      "  }\n"
+      "  _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);\n"
       "  break;\n");
+    if (end_tag_ != 0) {
+      printer->Print(
+        "$end_tag$:\n"
+        "  return;\n",
+        "end_tag", SimpleItoa(end_tag_));
+    }
   }
   for (int i = 0; i < fields_by_number().size(); i++) {
     const FieldDescriptor* field = fields_by_number()[i];
diff --git a/src/google/protobuf/compiler/csharp/csharp_message.h b/src/google/protobuf/compiler/csharp/csharp_message.h
index 5e0ac96..8174023 100644
--- a/src/google/protobuf/compiler/csharp/csharp_message.h
+++ b/src/google/protobuf/compiler/csharp/csharp_message.h
@@ -59,6 +59,7 @@
   const Descriptor* descriptor_;
   std::vector<const FieldDescriptor*> fields_by_number_;
   int has_bit_field_count_;
+  uint end_tag_;
 
   void GenerateMessageSerializationMethods(io::Printer* printer);
   void GenerateMergingMethods(io::Printer* printer);
@@ -71,7 +72,7 @@
 
   void AddDeprecatedFlag(io::Printer* printer);
   void AddSerializableAttribute(io::Printer* printer);
-  
+
   std::string class_name();
   std::string full_class_name();
 
diff --git a/src/google/protobuf/compiler/csharp/csharp_message_field.cc b/src/google/protobuf/compiler/csharp/csharp_message_field.cc
index 899cd7b..670c1be 100644
--- a/src/google/protobuf/compiler/csharp/csharp_message_field.cc
+++ b/src/google/protobuf/compiler/csharp/csharp_message_field.cc
@@ -103,8 +103,8 @@
       "$access_level$ bool Has$property_name$ {\n"
       "  get { return $name$_ != null; }\n"
       "}\n");
-    printer->Print( 
-      variables_, 
+    printer->Print(
+      variables_,
       "/// <summary>Clears the value of the $descriptor_name$ field</summary>\n");
     AddPublicMemberAttributes(printer);
     printer->Print(
@@ -259,7 +259,7 @@
 }
 
 void MessageOneofFieldGenerator::GenerateMergingCode(io::Printer* printer) {
-  printer->Print(variables_, 
+  printer->Print(variables_,
     "if ($property_name$ == null) {\n"
     "  $property_name$ = new $type_name$();\n"
     "}\n"
diff --git a/src/google/protobuf/compiler/csharp/csharp_primitive_field.cc b/src/google/protobuf/compiler/csharp/csharp_primitive_field.cc
index b83468d..87d51a9 100644
--- a/src/google/protobuf/compiler/csharp/csharp_primitive_field.cc
+++ b/src/google/protobuf/compiler/csharp/csharp_primitive_field.cc
@@ -69,7 +69,7 @@
   // (Basically, should null-handling code be in the getter or the setter?)
   if (IsProto2(descriptor_->file())) {
     printer->Print(
-      variables_, 
+      variables_,
       "private readonly static $type_name$ $property_name$DefaultValue = $default_value$;\n\n");
   }
 
@@ -121,7 +121,7 @@
     printer->Print(variables_, "/// <summary>Gets whether the \"$descriptor_name$\" field is set</summary>\n");
     AddPublicMemberAttributes(printer);
     printer->Print(
-      variables_, 
+      variables_,
       "$access_level$ bool Has$property_name$ {\n"
       "  get { return ");
     if (IsNullable(descriptor_)) {
diff --git a/src/google/protobuf/compiler/csharp/csharp_reflection_class.cc b/src/google/protobuf/compiler/csharp/csharp_reflection_class.cc
index 5ddd616..5b70f1a 100644
--- a/src/google/protobuf/compiler/csharp/csharp_reflection_class.cc
+++ b/src/google/protobuf/compiler/csharp/csharp_reflection_class.cc
@@ -234,7 +234,7 @@
   }
   // Generated message type
   printer->Print("new pbr::GeneratedClrTypeInfo(typeof($type_name$), $type_name$.Parser, ", "type_name", GetClassName(descriptor));
-  
+
   // Fields
   if (descriptor->field_count() > 0) {
       std::vector<std::string> fields;
@@ -273,7 +273,7 @@
 
   // Nested types
   if (descriptor->nested_type_count() > 0) {
-      // Need to specify array type explicitly here, as all elements may be null. 
+      // Need to specify array type explicitly here, as all elements may be null.
       printer->Print("new pbr::GeneratedClrTypeInfo[] { ");
       for (int i = 0; i < descriptor->nested_type_count(); i++) {
           WriteGeneratedCodeInfo(descriptor->nested_type(i), printer, i == descriptor->nested_type_count() - 1);
diff --git a/src/google/protobuf/compiler/csharp/csharp_repeated_enum_field.cc b/src/google/protobuf/compiler/csharp/csharp_repeated_enum_field.cc
index a69e97b..845fc2a 100644
--- a/src/google/protobuf/compiler/csharp/csharp_repeated_enum_field.cc
+++ b/src/google/protobuf/compiler/csharp/csharp_repeated_enum_field.cc
@@ -90,7 +90,7 @@
     "$name$_.WriteTo(output, _repeated_$name$_codec);\n");
 }
 
-void RepeatedEnumFieldGenerator::GenerateSerializedSizeCode(io::Printer* printer) {  
+void RepeatedEnumFieldGenerator::GenerateSerializedSizeCode(io::Printer* printer) {
   printer->Print(
     variables_,
     "size += $name$_.CalculateSize(_repeated_$name$_codec);\n");
diff --git a/src/google/protobuf/compiler/java/java_message.cc b/src/google/protobuf/compiler/java/java_message.cc
index c60e8c5..d28934a 100644
--- a/src/google/protobuf/compiler/java/java_message.cc
+++ b/src/google/protobuf/compiler/java/java_message.cc
@@ -1439,13 +1439,17 @@
     "public <T extends com.google.protobuf.Message> T unpack(\n"
     "    java.lang.Class<T> clazz)\n"
     "    throws com.google.protobuf.InvalidProtocolBufferException {\n"
-    "  if (!is(clazz)) {\n"
+    "  boolean invalidClazz = false;\n"
+    "  if (cachedUnpackValue != null) {\n"
+    "    if (cachedUnpackValue.getClass() == clazz) {\n"
+    "      return (T) cachedUnpackValue;\n"
+    "    }\n"
+    "    invalidClazz = true;\n"
+    "  }\n"
+    "  if (invalidClazz || !is(clazz)) {\n"
     "    throw new com.google.protobuf.InvalidProtocolBufferException(\n"
     "        \"Type of the Any message does not match the given class.\");\n"
     "  }\n"
-    "  if (cachedUnpackValue != null) {\n"
-    "    return (T) cachedUnpackValue;\n"
-    "  }\n"
     "  T defaultInstance =\n"
     "      com.google.protobuf.Internal.getDefaultInstance(clazz);\n"
     "  T result = (T) defaultInstance.getParserForType()\n"
diff --git a/src/google/protobuf/compiler/objectivec/objectivec_enum.cc b/src/google/protobuf/compiler/objectivec/objectivec_enum.cc
index 3b2ca55..f1330a5 100644
--- a/src/google/protobuf/compiler/objectivec/objectivec_enum.cc
+++ b/src/google/protobuf/compiler/objectivec/objectivec_enum.cc
@@ -92,6 +92,20 @@
       "\n",
       "name", name_);
 
+  // Swift 5 included SE0192 "Handling Future Enum Cases"
+  //   https://github.com/apple/swift-evolution/blob/master/proposals/0192-non-exhaustive-enums.md
+  // Since a .proto file can get new values added to an enum at any time, they
+  // are effectively "non-frozen". Even in a proto3 syntax file where there is
+  // support for the unknown value, an edit to the file can always add a new
+  // value moving something from unknown to known. Since Swift is now ABI
+  // stable, it also means a binary could contain Swift compiled against one
+  // version of the .pbobjc.h file, but finally linked against an enum with
+  // more cases. So the Swift code will always have to treat ObjC Proto Enums
+  // as "non-frozen". The default behavior in SE0192 is for all objc enums to
+  // be "non-frozen" unless marked as otherwise, so this means this generation
+  // doesn't have to bother with the `enum_extensibility` attribute, as the
+  // default will be what is needed.
+
   printer->Print("$comments$typedef$deprecated_attribute$ GPB_ENUM($name$) {\n",
                  "comments", enum_comments,
                  "deprecated_attribute", GetOptionalDeprecatedAttribute(descriptor_, descriptor_->file()),
diff --git a/src/google/protobuf/compiler/ruby/ruby_generator.cc b/src/google/protobuf/compiler/ruby/ruby_generator.cc
index d6aa1f0..c5d9809 100644
--- a/src/google/protobuf/compiler/ruby/ruby_generator.cc
+++ b/src/google/protobuf/compiler/ruby/ruby_generator.cc
@@ -65,7 +65,7 @@
     google::protobuf::io::Printer* printer);
 std::string DefaultValueForField(
     const google::protobuf::FieldDescriptor* field);
-  
+
 template<class numeric_type>
 std::string NumberToString(numeric_type value) {
   std::ostringstream os;
@@ -150,7 +150,7 @@
     case FieldDescriptor::CPPTYPE_STRING: {
       std::ostringstream os;
       string default_str = field->default_value_string();
-      
+
       if (field->type() == FieldDescriptor::TYPE_STRING) {
         os << "\"" << default_str << "\"";
       } else if (field->type() == FieldDescriptor::TYPE_BYTES) {
@@ -224,7 +224,7 @@
 	", default: $default$",
 	"default", DefaultValueForField(field));
     }
-    
+
     printer->Print("\n");
   }
 }
@@ -252,7 +252,7 @@
     *error = "Extensions are not yet supported for proto2 .proto files.";
     return false;
   }
-  
+
   // Don't generate MapEntry messages -- we use the Ruby extension's native
   // support for map fields instead.
   if (message->options().map_entry()) {
diff --git a/src/google/protobuf/stubs/stringpiece.h b/src/google/protobuf/stubs/stringpiece.h
index bb5aeed..2ae3881 100644
--- a/src/google/protobuf/stubs/stringpiece.h
+++ b/src/google/protobuf/stubs/stringpiece.h
@@ -481,7 +481,7 @@
 template<> struct hash<StringPiece> {
   size_t operator()(const StringPiece& s) const {
     size_t result = 0;
-    for (const char *str = s.data(), *end = str + s.size(); str < end; str++) {  
+    for (const char *str = s.data(), *end = str + s.size(); str < end; str++) {
       result = 5 * result + static_cast<size_t>(*str);
     }
     return result;
diff --git a/src/google/protobuf/stubs/structurally_valid.cc b/src/google/protobuf/stubs/structurally_valid.cc
index b223968..0598427 100644
--- a/src/google/protobuf/stubs/structurally_valid.cc
+++ b/src/google/protobuf/stubs/structurally_valid.cc
@@ -555,7 +555,7 @@
 
 bool IsStructurallyValidUTF8(const char* buf, int len) {
   if (!module_initialized_) return true;
-  
+
   int bytes_consumed = 0;
   UTF8GenericScanFastAscii(&utf8acceptnonsurrogates_obj,
                            buf, len, &bytes_consumed);
diff --git a/src/google/protobuf/stubs/time_test.cc b/src/google/protobuf/stubs/time_test.cc
index 53da948..4dd06a6 100644
--- a/src/google/protobuf/stubs/time_test.cc
+++ b/src/google/protobuf/stubs/time_test.cc
@@ -201,7 +201,7 @@
   time.month = 13;
   ASSERT_FALSE(DateTimeToSeconds(time, &seconds));
 }
-  
+
 TEST(DateTimeTest, StringFormat) {
   DateTime start, end;
   start.year = 1;
diff --git a/third_party/googletest b/third_party/googletest
index c3bb0ee..5ec7f0c 160000
--- a/third_party/googletest
+++ b/third_party/googletest
@@ -1 +1 @@
-Subproject commit c3bb0ee2a63279a803aaad956b9b26d74bf9e6e2
+Subproject commit 5ec7f0c4a113e2f18ac2c6cc7df51ad6afc24081
diff --git a/update_version.py b/update_version.py
index 7a961ae..7d27941 100755
--- a/update_version.py
+++ b/update_version.py
@@ -1,16 +1,25 @@
 #!/usr/bin/env python
+# Usage: ./update_version.py <MAJOR>.<MINOR>.<MICRO> [<RC version>]
+#
+# Example:
+# ./update_version.py 3.7.1 2
+#   => Version will become 3.7.1-rc-2 (beta)
+# ./update_version.py 3.7.1
+#   => Version will become 3.7.1 (stable)
 
 import datetime
 import re
 import sys
 from xml.dom import minidom
 
-if len(sys.argv) < 2:
+if len(sys.argv) < 2 or len(sys.argv) > 3:
   print """
 [ERROR] Please specify a version.
 
+./update_version.py <MAJOR>.<MINOR>.<MICRO> [<RC version>]
+
 Example:
-./update_version.py 2.1.3
+./update_version.py 3.7.1 2
 """
   exit(1)
 
@@ -21,10 +30,14 @@
 [ERROR] Version must be in the format <MAJOR>.<MINOR>.<MICRO>
 
 Example:
-./update_version.py 2.1.3
+./update_version.py 3.7.3
 """
   exit(1)
 
+RC_VERSION = 0
+if len(sys.argv) > 2:
+  RC_VERSION = int(sys.argv[2])
+
 
 def Find(elem, tagname):
   for child in elem.childNodes:
@@ -41,6 +54,13 @@
   elem.firstChild.replaceWholeText(text)
 
 
+def GetFullVersion(rc_suffix = '-rc-'):
+  if RC_VERSION == 0:
+    return NEW_VERSION
+  else:
+    return '%s%s%s' % (NEW_VERSION, rc_suffix, RC_VERSION)
+
+
 def RewriteXml(filename, rewriter, add_xml_prefix=True):
   document = minidom.parse(filename)
   rewriter(document)
@@ -74,7 +94,7 @@
     lambda line : re.sub(
       r'^AC_INIT\(\[Protocol Buffers\],\[.*\],\[protobuf@googlegroups.com\],\[protobuf\]\)$',
       ('AC_INIT([Protocol Buffers],[%s],[protobuf@googlegroups.com],[protobuf])'
-        % NEW_VERSION),
+        % GetFullVersion()),
       line))
 
 
@@ -120,44 +140,44 @@
   RewriteXml('csharp/src/Google.Protobuf/Google.Protobuf.csproj',
     lambda document : ReplaceText(
       Find(Find(document.documentElement, 'PropertyGroup'), 'VersionPrefix'),
-      NEW_VERSION),
+      GetFullVersion(rc_suffix = '-rc.')),
     add_xml_prefix=False)
 
   RewriteXml('csharp/Google.Protobuf.Tools.nuspec',
     lambda document : ReplaceText(
       Find(Find(document.documentElement, 'metadata'), 'version'),
-      NEW_VERSION))
+      GetFullVersion(rc_suffix = '-rc.')))
 
 
 def UpdateJava():
   RewriteXml('java/pom.xml',
     lambda document : ReplaceText(
-      Find(document.documentElement, 'version'), NEW_VERSION))
+      Find(document.documentElement, 'version'), GetFullVersion()))
 
   RewriteXml('java/bom/pom.xml',
     lambda document : ReplaceText(
-      Find(document.documentElement, 'version'), NEW_VERSION))
+      Find(document.documentElement, 'version'), GetFullVersion()))
 
   RewriteXml('java/core/pom.xml',
     lambda document : ReplaceText(
       Find(Find(document.documentElement, 'parent'), 'version'),
-      NEW_VERSION))
+      GetFullVersion()))
 
   RewriteXml('java/util/pom.xml',
     lambda document : ReplaceText(
       Find(Find(document.documentElement, 'parent'), 'version'),
-      NEW_VERSION))
+      GetFullVersion()))
 
   RewriteXml('protoc-artifacts/pom.xml',
     lambda document : ReplaceText(
-      Find(document.documentElement, 'version'), NEW_VERSION))
+      Find(document.documentElement, 'version'), GetFullVersion()))
 
 
 def UpdateJavaScript():
   RewriteTextFile('js/package.json',
     lambda line : re.sub(
       r'^  "version": ".*",$',
-      '  "version": "%s",' % NEW_VERSION,
+      '  "version": "%s",' % GetFullVersion(rc_suffix = '-rc.'),
       line))
 
 
@@ -185,7 +205,7 @@
   RewriteTextFile('Protobuf.podspec',
     lambda line : re.sub(
       r"^  s.version  = '.*'$",
-      "  s.version  = '%s'" % NEW_VERSION,
+      "  s.version  = '%s'" % GetFullVersion(rc_suffix = '-rc.'),
       line))
 
 
@@ -203,8 +223,12 @@
 
     root = document.documentElement
     version = Find(root, 'version')
-    ReplaceText(Find(version, 'release'), NEW_VERSION)
+    ReplaceText(Find(version, 'release'), GetFullVersion(rc_suffix = 'RC'))
     ReplaceText(Find(version, 'api'), NEW_VERSION)
+    stability = Find(root, 'stability')
+    ReplaceText(Find(version, 'release'),
+        'stable' if RC_VERSION == 0 else 'beta')
+    ReplaceText(Find(version, 'api'), 'stable' if RC_VERSION == 0 else 'beta')
     now = datetime.datetime.now()
     ReplaceText(Find(root, 'date'), now.strftime('%Y-%m-%d'))
     ReplaceText(Find(root, 'time'), now.strftime('%H:%M:%S'))
@@ -215,7 +239,6 @@
           % NEW_VERSION)
         return
     changelog.appendChild(document.createTextNode(' '))
-    stability = Find(root, 'stability')
     release = CreateNode('release', 2, [
         CreateNode('version', 3, [
           FindAndClone(version, 'release'),
@@ -234,18 +257,24 @@
     changelog.appendChild(document.createTextNode('\n '))
   RewriteXml('php/ext/google/protobuf/package.xml', Callback)
 
+  RewriteTextFile('php/ext/google/protobuf/protobuf.h',
+    lambda line : re.sub(
+      r"^#define PHP_PROTOBUF_VERSION .*$",
+      "#define PHP_PROTOBUF_VERSION \"%s\"" % GetFullVersion(rc_suffix = 'RC'),
+      line))
+
 def UpdatePython():
   RewriteTextFile('python/google/protobuf/__init__.py',
     lambda line : re.sub(
       r"^__version__ = '.*'$",
-      "__version__ = '%s'" % NEW_VERSION,
+      "__version__ = '%s'" % GetFullVersion(rc_suffix = 'rc'),
       line))
 
 def UpdateRuby():
   RewriteTextFile('ruby/google-protobuf.gemspec',
     lambda line : re.sub(
       r'^  s.version     = ".*"$',
-      '  s.version     = "%s"' % NEW_VERSION,
+      '  s.version     = "%s"' % GetFullVersion(rc_suffix = '.rc.'),
       line))